diff --git a/test/raytracer/Makefile b/test/raytracer/Makefile
index 2812909737d97ceb74cc5215e836cc5590d74ee3..dea57af90fad98c12d070865f2b94d8c0ab7a672 100644
--- a/test/raytracer/Makefile
+++ b/test/raytracer/Makefile
@@ -1,5 +1,5 @@
 CC=../../ccomp 
-CFLAGS=-U__GNUC__ -stdlib ../../runtime -dclight -dasm
+CFLAGS=-stdlib ../../runtime -dparse -dclight -dasm -fstruct-passing -fstruct-assign
 LIBS=
 TIME=xtime -mintime 2.0
 
@@ -11,7 +11,7 @@ render: $(OBJS)
 	$(CC) $(CFLAGS) -o render $(OBJS) $(LIBS)
 
 clean:
-	rm -f *.o *.light.c *.s *.ppm render
+	rm -f *.o *.parsed.c *.light.c *.s *.ppm render
 
 include .depend
 
diff --git a/test/raytracer/arrays.h b/test/raytracer/arrays.h
index 47634f62d9e59b92e8b26c020569ec118de0663c..fe65af0c44d685e6d3878528da9a3b45532d2331 100644
--- a/test/raytracer/arrays.h
+++ b/test/raytracer/arrays.h
@@ -18,14 +18,8 @@ struct array * copy_array(int eltsize, struct array * arr, int extrasize);
 
 #define get_array(ty,arr,idx) (data_array(ty,arr)[idx])
 
-#define get_array_large(dst,ty,arr,idx) \
-  ASSIGN(dst, data_array(ty,arr)[idx])
-
 #define set_array(ty,arr,idx,newval) (data_array(ty,arr)[idx] = (newval))
 
-#define set_array_large(ty,arr,idx,newval) \
-  ASSIGN(data_array(ty,arr)[idx], newval)
-
 #define extend_array(ty,arr) \
   if ((arr)->size >= (arr)->capacity) grow_array(sizeof(ty), (arr)); \
   (arr)->size++
diff --git a/test/raytracer/config.h b/test/raytracer/config.h
index ed5b8478cbacfc0ca6b3bcdf45d6c7c250639891..49361dc5d837f237f17f48ef3990eac1dd75a4a3 100644
--- a/test/raytracer/config.h
+++ b/test/raytracer/config.h
@@ -1,9 +1,9 @@
 #include <math.h>
+#include <assert.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <assert.h>
 
 #ifdef SINGLE_PRECISION
 typedef float flt;
@@ -11,17 +11,6 @@ typedef float flt;
 typedef double flt;
 #endif
 
-#if 0
-extern void abord(void);
-
-#define assert(cond) \
-  if (!(cond)) { fprintf(stderr, "%s:%u: failed assertion\n", __FILE__, __LINE__); abort(); }
-
-#endif
-
-#define ASSIGN(lv,rv) memcpy(&(lv), &(rv), sizeof(rv))
-
 void arena_init(void);
 void arena_clear(void);
 void * arena_alloc(int size);
-
diff --git a/test/raytracer/eval.c b/test/raytracer/eval.c
index 4d3f3dcc4523106ad7966a01997f5ca97709edd7..7c3cb93218116a62f99f2f8833111148f136d072 100644
--- a/test/raytracer/eval.c
+++ b/test/raytracer/eval.c
@@ -38,7 +38,7 @@ static int lookup(struct array * env, char * name, /*out*/ struct value * res)
   for (i = env->size - 1; i >= 0; i--) {
     struct binding * b = &get_array(struct binding, env, i);
     if (name == b->name) {
-      ASSIGN(*res, b->val);
+      *res = b->val;
       return 1;
     }
   }
@@ -55,7 +55,7 @@ static void assign(struct array * env, char * name, struct value * newval)
     b = &get_array(struct binding, env, i);
     if (! b->mutable) break;
     if (name == b->name) {
-      ASSIGN(b->val, *newval);
+      b->val = *newval;
       return;
     }
   }
@@ -63,7 +63,7 @@ static void assign(struct array * env, char * name, struct value * newval)
   b = &get_array(struct binding, env, env->size - 1);
   b->name = name;
   b->mutable = 1;
-  ASSIGN(b->val, *newval);
+  b->val = *newval;
 }
 
 /* Take an immutable copy of an environment */
@@ -173,22 +173,11 @@ static void print_value(struct value * s)
 static struct value main_stack[MAIN_STACK_SIZE];
 static struct value surface_stack[SURFACE_STACK_SIZE];
 
-/* Error handling functions */
-#define ERRORFUN(name, msg) \
-  static void name(void) { fprintf(stderr, msg); exit(2); }
-
-ERRORFUN(stack_overflow, "Stack overflow\n")
-ERRORFUN(stack_underflow, "Stack underflow\n")
-ERRORFUN(type_error, "Type error\n")
-ERRORFUN(division_by_zero, "Division by zero\n")
-ERRORFUN(bound_error, "Out-of-bound array access\n")
-ERRORFUN(negative_sqrt, "Square root of negative number\n")
-
 /* Macros for stack checking and type checking */
 
-#define push() if (--sp < bos) stack_overflow()
-#define can_pop(n) if (sp + (n) > tos) stack_underflow()
-#define check(n,ty) if (sp[n].tag != ty) type_error()
+#define push() if (--sp < bos) goto stack_overflow
+#define can_pop(n) if (sp + (n) > tos) goto stack_underflow
+#define check(n,ty) if (sp[n].tag != ty) goto type_error
 
 /* Execute the given token list in the given environment */
 
@@ -238,7 +227,7 @@ static struct value * execute_list(struct array * code,
       struct array * a = new_array(struct value, sz);
       int j;
       a->size = sz;
-      for (j = 0; j < sz; j++) set_array_large(struct value, a, j, sp[-1-j]);
+      for (j = 0; j < sz; j++) set_array(struct value, a, j, sp[-1-j]);
       push();
       sp[0].tag = Arr; sp[0].u.arr = a;
       break;
@@ -287,7 +276,7 @@ static struct value * execute_list(struct array * code,
       can_pop(1);
       check(0, Clos);
       sp[0].tag = Obj;
-      sp[0].u.obj = cone(&sp[0].u.clos);
+      sp[0].u.obj = cone(sp[0].u.clos);
       break;
     case Op_cos:
       can_pop(1);
@@ -298,13 +287,13 @@ static struct value * execute_list(struct array * code,
       can_pop(1);
       check(0, Clos);
       sp[0].tag = Obj;
-      sp[0].u.obj = cube(&sp[0].u.clos);
+      sp[0].u.obj = cube(sp[0].u.clos);
       break;
     case Op_cylinder:
       can_pop(1);
       check(0, Clos);
       sp[0].tag = Obj;
-      sp[0].u.obj = cylinder(&sp[0].u.clos);
+      sp[0].u.obj = cylinder(sp[0].u.clos);
       break;
     case Op_difference:
       can_pop(2);
@@ -317,7 +306,7 @@ static struct value * execute_list(struct array * code,
       can_pop(2);
       check(1, I);
       check(0, I);
-      if (sp[0].u.i == 0) division_by_zero();
+      if (sp[0].u.i == 0) goto division_by_zero;
       sp[1].u.i = sp[1].u.i / sp[0].u.i;
       sp += 1;
       break;
@@ -365,8 +354,8 @@ static struct value * execute_list(struct array * code,
       check(0, I);
       a = sp[1].u.arr;
       idx = sp[0].u.i;
-      if (idx < 0 || idx >= a->size) bound_error();
-      get_array_large(sp[1], struct value, a, idx);
+      if (idx < 0 || idx >= a->size) goto bound_error;
+      sp[1] = get_array(struct value, a, idx);
       sp++;
       break;
     }
@@ -439,7 +428,7 @@ static struct value * execute_list(struct array * code,
       can_pop(2);
       check(1, I);
       check(0, I);
-      if (sp[0].u.i == 0) division_by_zero();
+      if (sp[0].u.i == 0) goto division_by_zero;
       sp[1].u.i = sp[1].u.i % sp[0].u.i;
       sp += 1;
       break;
@@ -471,7 +460,7 @@ static struct value * execute_list(struct array * code,
       can_pop(1);
       check(0, Clos);
       sp[0].tag = Obj;
-      sp[0].u.obj = plane(&sp[0].u.clos);
+      sp[0].u.obj = plane(sp[0].u.clos);
       break;
     case Op_point: {
       struct point * p;
@@ -562,7 +551,7 @@ static struct value * execute_list(struct array * code,
       can_pop(1);
       check(0, Clos);
       sp[0].tag = Obj;
-      sp[0].u.obj = sphere(&sp[0].u.clos);
+      sp[0].u.obj = sphere(sp[0].u.clos);
       break;
     case Op_spotlight:
       can_pop(5);
@@ -579,7 +568,7 @@ static struct value * execute_list(struct array * code,
     case Op_sqrt:
       can_pop(1);
       check(0, R);
-      if (sp[0].u.r < 0) negative_sqrt();
+      if (sp[0].u.r < 0) goto negative_sqrt;
       sp[0].u.r = sqrt(sp[0].u.r);
       break;
     case Op_subi:
@@ -627,11 +616,32 @@ static struct value * execute_list(struct array * code,
     }
   }
   return sp;
+  /* Error handling */
+ stack_overflow:
+  fprintf(stderr, "Stack overflow\n");
+  goto print_context;
+ stack_underflow:
+  fprintf(stderr, "Stack underflow\n");
+  goto print_context;
+ type_error:
+  fprintf(stderr, "Type error\n");
+  goto print_context;
+ division_by_zero:
+  fprintf(stderr, "Division by zero\n");
+  goto print_context;
+ bound_error:
+  fprintf(stderr, "Out-of-bound array access\n");
+  goto print_context;
+ negative_sqrt:
+  fprintf(stderr, "Square root of negative number\n");
+ print_context:
+  fprintf(stderr, "(operation: %s, PC: %d)\n", operator_names[t->tag], i);
+  exit(2);
 }
 
 /* Evaluate a surface function */
 
-void surface_function(struct closure * clos, int face, flt u, flt v,
+void surface_function(struct closure clos, int face, flt u, flt v,
                       /*out*/ struct surface_characteristics * sc)
 {
   struct value * sp;
@@ -643,7 +653,7 @@ void surface_function(struct closure * clos, int face, flt u, flt v,
   sp[0].tag = R;
   sp[0].u.i = v;
   sp =
-    execute_list(clos->code, clos->env, surface_stack,
+    execute_list(clos.code, clos.env, surface_stack,
                  surface_stack + SURFACE_STACK_SIZE, sp);
   if (sp != surface_stack + SURFACE_STACK_SIZE - 4 ||
       sp[0].tag != R ||
diff --git a/test/raytracer/eval.h b/test/raytracer/eval.h
index 610b5d96734bd49a7b2647e0f3c0985aa20b9a92..88facfea203b5f9b23555b3e99631c9eb3d78a8b 100644
--- a/test/raytracer/eval.h
+++ b/test/raytracer/eval.h
@@ -14,5 +14,5 @@ struct surface_characteristics {
 
 void execute_program(struct array * toklist);
 
-void surface_function(struct closure * clos, int face, flt u, flt v,
+void surface_function(struct closure clos, int face, flt u, flt v,
                       /*out*/ struct surface_characteristics * sc);
diff --git a/test/raytracer/gmllexer.c b/test/raytracer/gmllexer.c
index 04f8df814ae4a8eef89c52fb85e2e01011d724f9..a8594dd37189b666ea691c5c4bc697a4e01d150e 100644
--- a/test/raytracer/gmllexer.c
+++ b/test/raytracer/gmllexer.c
@@ -1,14 +1,10 @@
 /* Lexer for GML */
 
 #include "config.h"
+#include <ctype.h>
 #include "gmllexer.h"
 #include "gml.h"
 
-#define isdigit(c) (c >= '0' && c <= '9')
-#define isalpha(c) ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
-#define isalnum(c) (isdigit(c) || isalpha(c))
-#define isprint(c) (c >= ' ' && c <= 126)
-
 struct lexeme current_lexeme;
 
 struct bucket {
@@ -91,7 +87,7 @@ static void get_binder(void)
   current_lexeme.kind = BINDER;
 }
 
-static int get_number(int firstchar)
+static void get_number(int firstchar)
 {
   int c, pos, is_real;
 
@@ -102,7 +98,7 @@ static int get_number(int firstchar)
   if (c == '-') {
     STORE_BUFFER(pos, c);
     c = getchar();
-    if (! isdigit(c)) return -1;
+    if (! isdigit(c)) goto bad_number;
   }
   /* Decimal number */
   do {
@@ -114,7 +110,7 @@ static int get_number(int firstchar)
     is_real = 1;
     STORE_BUFFER(pos, c);
     c = getchar();
-    if (! isdigit(c)) return -1;
+    if (! isdigit(c)) goto bad_number;
     do {
       STORE_BUFFER(pos, c);
       c = getchar();
@@ -129,7 +125,7 @@ static int get_number(int firstchar)
       STORE_BUFFER(pos, c);
       c = getchar();
     }
-    if (! isdigit(c)) return -1;
+    if (! isdigit(c)) goto bad_number;
     do {
       STORE_BUFFER(pos, c);
       c = getchar();
@@ -145,23 +141,29 @@ static int get_number(int firstchar)
     current_lexeme.kind = INTEGER;
     current_lexeme.u.i = atoi(buffer);
   }
-  return 0;
+  return;
+ bad_number:
+  fprintf(stderr, "Illegal number\n");
+  exit(2);
 }
 
-static int get_string(void)
+static void get_string()
 {
   int c, pos;
   pos = 0;
   while (1) {
     c = getchar();
     if (c == '"') break;
-    if (! isprint(c)) return -1;
+    if (! isprint(c)) goto bad_string;
     STORE_BUFFER(pos, c);
   }
   buffer[pos] = 0;
   current_lexeme.kind = STRING;
   current_lexeme.u.s = strdup(buffer);
-  return 0;
+  return;
+ bad_string:
+  fprintf(stderr, "Illegal string literal\n");
+  exit(2);
 }
 
 void get_lexeme(void)
@@ -169,49 +171,39 @@ void get_lexeme(void)
   int c;
 
   if (current_lexeme.kind != NONE) return;
-  while (1) {
-    c = getchar();
-    switch (c) {
-    case EOF:
-      current_lexeme.kind = END_OF_FILE; break;
-    case ' ': case '\n': case '\t': case '\r': case 11:
-      continue;
-    case '%':
-      do { c = getchar(); } while (c != '\n' && c != EOF);
-      continue;
-    case '/':
-      get_binder(); break;
-    case '-': case '0': case '1': case '2': case '3': case '4':
-    case '5': case '6': case '7': case '8': case '9':
-      if (get_number(c) == -1) {
-        fprintf(stderr, "Bad number\n");
-        exit(2);
-      }
-      break;
-    case '"':
-      if (get_string() == -1) {
-        fprintf(stderr, "Bad string literal\n");
-        exit(2);
-      }
-      break;
-    case '{':
-      current_lexeme.kind = LBRACE; break;
-    case '}':
-      current_lexeme.kind = RBRACE; break;
-    case '[':
-      current_lexeme.kind = LBRACKET; break;
-    case ']':
-      current_lexeme.kind = RBRACKET; break;
-    default:
-      if (isalpha(c)) {
-        get_ident(c);
-      } else {
-        fprintf(stderr, "Illegal character `%c'\n", c);
-        exit(2);
-      }
-      break;
+ again:
+  c = getchar();
+  switch (c) {
+  case EOF:
+    current_lexeme.kind = END_OF_FILE; break;
+  case ' ': case '\n': case '\t': case '\r': case 11:
+    goto again;
+  case '%':
+    do { c = getchar(); } while (c != '\n' && c != EOF);
+    goto again;
+  case '/':
+    get_binder(); break;
+  case '-': case '0': case '1': case '2': case '3': case '4':
+  case '5': case '6': case '7': case '8': case '9':
+    get_number(c); break;
+  case '"':
+    get_string(); break;
+  case '{':
+    current_lexeme.kind = LBRACE; break;
+  case '}':
+    current_lexeme.kind = RBRACE; break;
+  case '[':
+    current_lexeme.kind = LBRACKET; break;
+  case ']':
+    current_lexeme.kind = RBRACKET; break;
+  default:
+    if (isalpha(c)) {
+      get_ident(c);
+    } else {
+      fprintf(stderr, "Illegal character `%c'\n", c);
+      exit(2);
     }
-    return;
+    break;
   }
 }
 
diff --git a/test/raytracer/gmlparser.c b/test/raytracer/gmlparser.c
index b0a6cbc19a6bd9d79b7e1dd9188bb13e839351ba..dc05105227fe04aed5facdb97f257bc3d38db219 100644
--- a/test/raytracer/gmlparser.c
+++ b/test/raytracer/gmlparser.c
@@ -82,7 +82,7 @@ static struct array * parse_tokenlist(void)
   int i = 0;
   while (parse_token(&t)) {
     extend_array(struct tok, a);
-    set_array_large(struct tok, a, i, t);
+    set_array(struct tok, a, i, t);
     i++;
   }
   return a;
diff --git a/test/raytracer/intersect.c b/test/raytracer/intersect.c
index c8a212603036d41c0ec6561bd9da3e3ae7d451cd..3b2d7b0dd7f8caddb52b6aba100086aaeacf9421 100644
--- a/test/raytracer/intersect.c
+++ b/test/raytracer/intersect.c
@@ -9,7 +9,7 @@
 
 /* Operations on interval lists */
 
-#define POS_INFTY 1e300
+#define POS_INFTY HUGE_VAL
 
 struct intervlist {
   flt beg;
diff --git a/test/raytracer/light.c b/test/raytracer/light.c
index 1c90104ce744ba1eeddbf9859e0e03d6d861d7ac..60d979a7049d2b31f4fd3f90aa77ad1f6033b93a 100644
--- a/test/raytracer/light.c
+++ b/test/raytracer/light.c
@@ -10,8 +10,8 @@ struct light * dirlight(struct point * dir, struct point * c)
 {
   struct light * l = arena_alloc(sizeof(struct light));
   l->kind = Directional;
-  ASSIGN(l->u.directional.dir, *dir);
-  ASSIGN(l->u.directional.col, *c);
+  l->u.directional.dir = *dir;
+  l->u.directional.col = *c;
   return l;
 }
 
@@ -19,8 +19,8 @@ struct light * pointlight(struct point * orig, struct point * c)
 {
   struct light * l = arena_alloc(sizeof(struct light));
   l->kind = Pointlight;
-  ASSIGN(l->u.point.orig, *orig);
-  ASSIGN(l->u.point.col, *c);
+  l->u.point.orig = *orig;
+  l->u.point.col = *c;
   return l;
 }
 
@@ -30,9 +30,9 @@ struct light * spotlight(struct point * pos, struct point * at,
   struct light * l = arena_alloc(sizeof(struct light));
   struct vector uv;
   l->kind = Spot;
-  ASSIGN(l->u.spot.orig, *pos);
-  ASSIGN(l->u.spot.at, *at);
-  ASSIGN(l->u.spot.col, *c);
+  l->u.spot.orig = *pos;
+  l->u.spot.at = *at;
+  l->u.spot.col = *c;
   l->u.spot.cutoff = cutoff;
   l->u.spot.exponent = exp;
   between(at, pos, &uv);
@@ -81,9 +81,7 @@ static void color_from_light(struct object * scene,
   /* Intensity of light source at object */
   switch (light->kind) {
   case Directional:
-    i.x = light->u.directional.col.x;
-    i.y = light->u.directional.col.y;
-    i.z = light->u.directional.col.z;
+    i = light->u.directional.col;
     break;
   case Pointlight:
     att = 100.0 / (99.0 + dist2(pt, &light->u.point.orig));
diff --git a/test/raytracer/matrix.c b/test/raytracer/matrix.c
index 8814346891ed6dd4911d4058ed66372c5dbedf0c..5c85c7b4869f823085b96f4b763b529e96a639fa 100644
--- a/test/raytracer/matrix.c
+++ b/test/raytracer/matrix.c
@@ -3,12 +3,6 @@
 #include "vector.h"
 #include "matrix.h"
 
-struct matrix matrix_identity = {
-  1.0,  0.0,  0.0,  0.0,
-  0.0,  1.0,  0.0,  0.0,
-  0.0,  0.0,  1.0,  0.0,
-};
-
 void apply_to_point(struct matrix * m, struct point * p,
                                   /*out*/ struct point * r)
 {
@@ -25,7 +19,13 @@ void apply_to_vect(struct matrix * m, struct vector * v,
   r->dz = m->zx * v->dx + m->zy * v->dy + m->zz * v->dz;
 }
 
+static struct matrix matrix_identity = {
+  1.0,  0.0,  0.0,  0.0,
+  0.0,  1.0,  0.0,  0.0,
+  0.0,  0.0,  1.0,  0.0,
+};
 
+struct matrix * mid = &matrix_identity;
 
 struct matrix * mtranslate(flt sx, flt sy, flt sz)
 {
diff --git a/test/raytracer/matrix.h b/test/raytracer/matrix.h
index 4b9f4346eb0555a227a3f227f96b8962c8905561..5ab63b33c0f07b992006cffbe380735263aa1d1c 100644
--- a/test/raytracer/matrix.h
+++ b/test/raytracer/matrix.h
@@ -8,8 +8,7 @@ void apply_to_point(struct matrix * m, struct point * p,
                     /*out*/ struct point * r);
 void apply_to_vect(struct matrix * m, struct vector * v,
                    /*out*/ struct vector * r);
-extern struct matrix matrix_identity;
-#define mid (&matrix_identity)
+extern struct matrix * mid;
 struct matrix * mtranslate(flt sx, flt sy, flt sz);
 struct matrix * mscale(flt sx, flt sy, flt sz);
 struct matrix * mrotatex(flt a);
diff --git a/test/raytracer/object.c b/test/raytracer/object.c
index 3dd6e77e467373993d75867a7be0215cc75d4e39..c7e5f53fe96594f5dd03e25ac9a63f6906fa47ea 100644
--- a/test/raytracer/object.c
+++ b/test/raytracer/object.c
@@ -6,30 +6,30 @@
 #include "object.h"
 #include "matrix.h"
 
-static struct object * new_object(int kind, struct closure * c)
+static struct object * new_object(int kind, struct closure c)
 {
   struct object * o = arena_alloc(sizeof(struct object));
   o->kind = kind;
-  ASSIGN(o->surf, *c);
+  o->surf = c;
   o->world2obj = o->obj2world = mid;
   o->max_scale_applied = 1.0;
   o->radius = BS_NOT_COMPUTED;
   return o;
 }
 
-struct object * cone(struct closure * c)
+struct object * cone(struct closure c)
 { return new_object(Cone, c); }
 
-struct object * cube(struct closure * c)
+struct object * cube(struct closure c)
 { return new_object(Cube, c); }
 
-struct object * cylinder(struct closure * c)
+struct object * cylinder(struct closure c)
 { return new_object(Cylinder, c); }
 
-struct object * plane(struct closure * c)
+struct object * plane(struct closure c)
 { return new_object(Plane, c); }
 
-struct object * sphere(struct closure * c)
+struct object * sphere(struct closure c)
 { return new_object(Sphere, c); }
 
 static struct object * transform(struct object * o,
@@ -47,7 +47,7 @@ static struct object * transform(struct object * o,
     no->o2 = transform(o->o2, t, tinv, scale);
     break;
   default:
-    ASSIGN(no->surf, o->surf);
+    no->surf = o->surf;
     no->world2obj = mcompose(o->world2obj, tinv);
     no->obj2world = mcompose(t, o->obj2world);
     no->max_scale_applied = o->max_scale_applied * scale;
@@ -212,3 +212,4 @@ void normal_vector(struct object * obj, struct point * p, int face,
   product(&tang_world1, &tang_world2, n);
   vnormalize(n, n);
 }
+
diff --git a/test/raytracer/object.h b/test/raytracer/object.h
index d890bda866b923c946a10f537f5ff77cf97bfccf..b5edd58ef9ff7087a31c6ccaa6b76f9afe4f2e89 100644
--- a/test/raytracer/object.h
+++ b/test/raytracer/object.h
@@ -12,11 +12,11 @@ struct object {
   flt radius;
 };
 
-struct object * cone(struct closure * c);
-struct object * cube(struct closure * c);
-struct object * cylinder(struct closure * c);
-struct object * plane(struct closure * c);
-struct object * sphere(struct closure * c);
+struct object * cone(struct closure c);
+struct object * cube(struct closure c);
+struct object * cylinder(struct closure c);
+struct object * plane(struct closure c);
+struct object * sphere(struct closure c);
 
 struct object * orotatex(struct object * o1, flt a);
 struct object * orotatey(struct object * o1, flt a);
diff --git a/test/raytracer/point.h b/test/raytracer/point.h
index b8d6ff0fcdae57bf2f311573cd28caecb11f3048..64bf5821e4e014836d7582b264a5a3a491f43567 100644
--- a/test/raytracer/point.h
+++ b/test/raytracer/point.h
@@ -2,7 +2,6 @@ struct point {
   flt x, y, z;
 };
 
-#if 0
 static inline flt dist2(struct point * p1, struct point * p2)
 {
   flt dx = p2->x - p1->x;
@@ -10,9 +9,4 @@ static inline flt dist2(struct point * p1, struct point * p2)
   flt dz = p2->z - p1->z;
   return dx * dx + dy * dy + dz * dz;
 }
-#else
-#define dist2(p1,p2) \
-  (((p2)->x - (p1)->x) * ((p2)->x - (p1)->x) + \
-   ((p2)->y - (p1)->y) * ((p2)->y - (p1)->y) + \
-   ((p2)->z - (p1)->z) * ((p2)->z - (p1)->z))
-#endif
+
diff --git a/test/raytracer/render.c b/test/raytracer/render.c
index 3678cb6faa30bb33bf596deff5a5c4a5bc8e5e9a..9d732806bc8b4c1f7bb327941fd52090102d7599 100644
--- a/test/raytracer/render.c
+++ b/test/raytracer/render.c
@@ -45,7 +45,7 @@ static void render_ray(struct point * amb,
   point_along(p, v, t, &inter_w);
   apply_to_point(bobj->world2obj, &inter_w, &inter_o);
   surface_coords(bobj, &inter_o, &face, &surf_u, &surf_v);
-  surface_function(&bobj->surf, face, surf_u, surf_v, &sc);
+  surface_function(bobj->surf, face, surf_u, surf_v, &sc);
   /* Construct the vectors on figure 4 */
   normal_vector(bobj, &inter_w, face, &n);
   dotprod = dotproduct(v, &n);
diff --git a/test/raytracer/simplify.c b/test/raytracer/simplify.c
index 7a4a5457194a8c6bd8d93fb2bee8da3d7a56575b..d8cbe64e2289f522a3ff544a8c3511d4539d8d54 100644
--- a/test/raytracer/simplify.c
+++ b/test/raytracer/simplify.c
@@ -7,7 +7,7 @@
 #include "object.h"
 #include "simplify.h"
 
-#define INFINITE_RADIUS 1e300
+#define INFINITE_RADIUS HUGE_VAL
 
 static flt cone_radius = 1.0;
 static flt cube_radius = 0.86602540378443859659; /* sqrt(3)/2 */
@@ -44,11 +44,11 @@ static inline void union_bs(struct object * t1, struct object * t2,
   if (dd2 <= rr2) {
     /* take the biggest sphere */
     if (t1->radius <= t2->radius) {
-      ASSIGN(obj->center, t2->center);
+      obj->center = t2->center;
       obj->radius = t2->radius;
       set_infinite(t2);
     } else {
-      ASSIGN(obj->center, t1->center);
+      obj->center = t1->center;
       obj->radius = t1->radius;
       set_infinite(t1);
     }
@@ -67,12 +67,12 @@ static inline void intersection_bs(struct object * t1, struct object * t2,
   flt dd2, rr, rr2, rpr, rpr2, diff, d, te1, te2, te3, te4, te, alpha;
 
   if (t1->radius >= INFINITE_RADIUS) {
-    ASSIGN(obj->center, t2->center);
+    obj->center = t2->center;
     obj->radius = t2->radius;
     return;
   }
   if (t2->radius >= INFINITE_RADIUS) {
-    ASSIGN(obj->center, t1->center);
+    obj->center = t1->center;
     obj->radius = t1->radius;
     return;
   }
@@ -83,11 +83,11 @@ static inline void intersection_bs(struct object * t1, struct object * t2,
   if (dd2 <= rr2) {
     /* take the smallest sphere */
     if (t2->radius <= t1->radius) {
-      ASSIGN(obj->center, t2->center);
+      obj->center = t2->center;
       obj->radius = t2->radius;
       set_infinite(t2);
     } else {
-      ASSIGN(obj->center, t1->center);
+      obj->center = t1->center;
       obj->radius = t1->radius;
       set_infinite(t1);
     }
@@ -96,19 +96,19 @@ static inline void intersection_bs(struct object * t1, struct object * t2,
   rpr = t1->radius + t2->radius;
   rpr2 = rpr * rpr;
   if (dd2 > rpr2) {
-    ASSIGN(obj->center, origin);
+    obj->center = origin;
     obj->radius = 0.0;
     return;
   }
   diff = t1->radius * t1->radius - t2->radius * t2->radius;
   if (dd2 <= diff) {
-    ASSIGN(obj->center, t2->center);
+    obj->center = t2->center;
     obj->radius = t2->radius;
     set_infinite(t2);
     return;
   }
   if (dd2 <= -diff) {
-    ASSIGN(obj->center, t1->center);
+    obj->center = t1->center;
     obj->radius = t1->radius;
     set_infinite(t1);
     return;
@@ -128,7 +128,7 @@ static inline void intersection_bs(struct object * t1, struct object * t2,
 static inline void difference_bs(struct object * t1, struct object * t2,
                                    struct object * obj)
 {
-  ASSIGN(obj->center, t1->center);
+  obj->center = t1->center;
   obj->radius = t1->radius;
   set_infinite(t1);
 }
@@ -150,7 +150,7 @@ void compute_bounding_spheres(struct object * obj)
     obj->radius = obj->max_scale_applied * cylinder_radius;
     break;
   case Plane:
-    ASSIGN(obj->center, plane_center);
+    obj->center = plane_center;
     obj->radius = INFINITE_RADIUS;
     break;
   case Sphere:
diff --git a/test/spass/.depend b/test/spass/.depend
new file mode 100644
index 0000000000000000000000000000000000000000..5348867d703b1dda4718595399a233b4ab581cfe
--- /dev/null
+++ b/test/spass/.depend
@@ -0,0 +1,130 @@
+analyze.o: analyze.c analyze.h search.h clause.h sharing.h term.h \
+  symbol.h list.h memory.h misc.h stringsx.h stack.h st.h foldfg.h \
+  flags.h unify.h context.h subst.h order.h sort.h hash.h subsumption.h \
+  component.h vector.h graph.h
+clause.o: clause.c clause.h sharing.h term.h symbol.h list.h memory.h \
+  misc.h stringsx.h stack.h st.h foldfg.h flags.h unify.h context.h \
+  subst.h order.h
+clock.o: clock.c clock.h misc.h
+closure.o: closure.c closure.h clause.h sharing.h term.h symbol.h list.h \
+  memory.h misc.h stringsx.h stack.h st.h foldfg.h flags.h unify.h \
+  context.h subst.h order.h table.h partition.h ras.h
+cnf.o: cnf.c cnf.h hasharray.h list.h memory.h misc.h renaming.h foldfg.h \
+  flags.h unify.h term.h symbol.h stringsx.h stack.h context.h subst.h \
+  vector.h resolution.h st.h subsumption.h component.h clause.h sharing.h \
+  order.h condensing.h search.h sort.h hash.h rules-inf.h rules-split.h \
+  rules-sort.h rules-ur.h defs.h rules-red.h doc-proof.h proofcheck.h \
+  options.h dfg.h tableau.h clock.h closure.h table.h partition.h ras.h
+component.o: component.c term.h symbol.h list.h memory.h misc.h \
+  stringsx.h stack.h component.h
+condensing.o: condensing.c subsumption.h misc.h unify.h term.h symbol.h \
+  list.h memory.h stringsx.h stack.h context.h subst.h component.h \
+  vector.h clause.h sharing.h st.h foldfg.h flags.h order.h condensing.h
+context.o: context.c context.h term.h symbol.h list.h memory.h misc.h \
+  stringsx.h stack.h
+defs.o: defs.c cnf.h hasharray.h list.h memory.h misc.h renaming.h \
+  foldfg.h flags.h unify.h term.h symbol.h stringsx.h stack.h context.h \
+  subst.h vector.h resolution.h st.h subsumption.h component.h clause.h \
+  sharing.h order.h condensing.h search.h sort.h hash.h defs.h
+dfgparser.o: dfgparser.c dfg.h list.h memory.h misc.h flags.h clause.h \
+  sharing.h term.h symbol.h stringsx.h stack.h st.h foldfg.h unify.h \
+  context.h subst.h order.h
+dfgscanner.o: dfgscanner.c misc.h memory.h symbol.h list.h stringsx.h \
+  term.h stack.h dfg.h flags.h clause.h sharing.h st.h foldfg.h unify.h \
+  context.h subst.h order.h dfgparser.h
+doc-proof.o: doc-proof.c doc-proof.h clause.h sharing.h term.h symbol.h \
+  list.h memory.h misc.h stringsx.h stack.h st.h foldfg.h flags.h unify.h \
+  context.h subst.h order.h search.h sort.h hash.h subsumption.h \
+  component.h vector.h proofcheck.h options.h dfg.h tableau.h
+flags.o: flags.c flags.h memory.h misc.h stringsx.h
+foldfg.o: foldfg.c foldfg.h flags.h memory.h misc.h unify.h term.h \
+  symbol.h list.h stringsx.h stack.h context.h subst.h
+graph.o: graph.c graph.h list.h memory.h misc.h
+hash.o: hash.c hash.h list.h memory.h misc.h
+hasharray.o: hasharray.c hasharray.h list.h memory.h misc.h
+iaparser.o: iaparser.c flags.h memory.h misc.h ia.h list.h symbol.h \
+  stringsx.h term.h stack.h foldfg.h unify.h context.h subst.h clause.h \
+  sharing.h st.h order.h
+iascanner.o: iascanner.c misc.h memory.h symbol.h list.h stringsx.h \
+  term.h stack.h ia.h flags.h iaparser.h
+kbo.o: kbo.c kbo.h term.h symbol.h list.h memory.h misc.h stringsx.h \
+  stack.h context.h foldfg.h flags.h unify.h subst.h order.h
+list.o: list.c list.h memory.h misc.h
+memory.o: memory.c memory.h misc.h
+misc.o: misc.c misc.h
+options.o: options.c options.h flags.h memory.h misc.h list.h stringsx.h
+order.o: order.c flags.h memory.h misc.h order.h term.h symbol.h list.h \
+  stringsx.h stack.h context.h kbo.h foldfg.h unify.h subst.h rpos.h
+partition.o: partition.c partition.h memory.h misc.h
+proofcheck.o: proofcheck.c proofcheck.h options.h flags.h memory.h misc.h \
+  list.h vector.h dfg.h clause.h sharing.h term.h symbol.h stringsx.h \
+  stack.h st.h foldfg.h unify.h context.h subst.h order.h tableau.h \
+  search.h sort.h hash.h subsumption.h component.h
+renaming.o: renaming.c renaming.h misc.h foldfg.h flags.h memory.h \
+  unify.h term.h symbol.h list.h stringsx.h stack.h context.h subst.h \
+  vector.h
+resolution.o: resolution.c resolution.h misc.h unify.h term.h symbol.h \
+  list.h memory.h stringsx.h stack.h context.h subst.h foldfg.h flags.h \
+  st.h subsumption.h component.h vector.h clause.h sharing.h order.h \
+  condensing.h
+rpos.o: rpos.c rpos.h misc.h term.h symbol.h list.h memory.h stringsx.h \
+  stack.h order.h context.h flags.h
+rules-inf.o: rules-inf.c rules-inf.h search.h clause.h sharing.h term.h \
+  symbol.h list.h memory.h misc.h stringsx.h stack.h st.h foldfg.h \
+  flags.h unify.h context.h subst.h order.h sort.h hash.h subsumption.h \
+  component.h vector.h rules-split.h rules-sort.h rules-ur.h defs.h
+rules-red.o: rules-red.c rules-red.h sort.h clause.h sharing.h term.h \
+  symbol.h list.h memory.h misc.h stringsx.h stack.h st.h foldfg.h \
+  flags.h unify.h context.h subst.h order.h hash.h subsumption.h \
+  component.h vector.h condensing.h search.h rules-split.h rules-inf.h \
+  rules-sort.h rules-ur.h defs.h doc-proof.h proofcheck.h options.h dfg.h \
+  tableau.h clock.h closure.h table.h partition.h ras.h
+rules-sort.o: rules-sort.c rules-sort.h sort.h clause.h sharing.h term.h \
+  symbol.h list.h memory.h misc.h stringsx.h stack.h st.h foldfg.h \
+  flags.h unify.h context.h subst.h order.h hash.h subsumption.h \
+  component.h vector.h
+rules-split.o: rules-split.c rules-split.h clause.h sharing.h term.h \
+  symbol.h list.h memory.h misc.h stringsx.h stack.h st.h foldfg.h \
+  flags.h unify.h context.h subst.h order.h search.h sort.h hash.h \
+  subsumption.h component.h vector.h
+rules-ur.o: rules-ur.c rules-ur.h clause.h sharing.h term.h symbol.h \
+  list.h memory.h misc.h stringsx.h stack.h st.h foldfg.h flags.h unify.h \
+  context.h subst.h order.h
+search.o: search.c search.h clause.h sharing.h term.h symbol.h list.h \
+  memory.h misc.h stringsx.h stack.h st.h foldfg.h flags.h unify.h \
+  context.h subst.h order.h sort.h hash.h subsumption.h component.h \
+  vector.h defs.h
+sharing.o: sharing.c sharing.h term.h symbol.h list.h memory.h misc.h \
+  stringsx.h stack.h st.h foldfg.h flags.h unify.h context.h subst.h
+sort.o: sort.c sort.h clause.h sharing.h term.h symbol.h list.h memory.h \
+  misc.h stringsx.h stack.h st.h foldfg.h flags.h unify.h context.h \
+  subst.h order.h hash.h subsumption.h component.h vector.h
+st.o: st.c st.h foldfg.h flags.h memory.h misc.h unify.h term.h symbol.h \
+  list.h stringsx.h stack.h context.h subst.h
+stack.o: stack.c stack.h misc.h
+strings.o: strings.c stringsx.h memory.h misc.h list.h
+subst.o: subst.c subst.h term.h symbol.h list.h memory.h misc.h \
+  stringsx.h stack.h unify.h context.h
+subsumption.o: subsumption.c subsumption.h misc.h unify.h term.h symbol.h \
+  list.h memory.h stringsx.h stack.h context.h subst.h component.h \
+  vector.h clause.h sharing.h st.h foldfg.h flags.h order.h
+symbol.o: symbol.c symbol.h list.h memory.h misc.h stringsx.h
+table.o: table.c table.h term.h symbol.h list.h memory.h misc.h \
+  stringsx.h stack.h partition.h
+tableau.o: tableau.c tableau.h list.h memory.h misc.h clause.h sharing.h \
+  term.h symbol.h stringsx.h stack.h st.h foldfg.h flags.h unify.h \
+  context.h subst.h order.h
+term.o: term.c term.h symbol.h list.h memory.h misc.h stringsx.h stack.h
+terminator.o: terminator.c terminator.h misc.h symbol.h list.h memory.h \
+  stringsx.h clause.h sharing.h term.h stack.h st.h foldfg.h flags.h \
+  unify.h context.h subst.h order.h
+top.o: top.c dfg.h list.h memory.h misc.h flags.h clause.h sharing.h \
+  term.h symbol.h stringsx.h stack.h st.h foldfg.h unify.h context.h \
+  subst.h order.h defs.h search.h sort.h hash.h subsumption.h component.h \
+  vector.h ia.h rules-inf.h rules-split.h rules-sort.h rules-ur.h \
+  terminator.h rules-red.h condensing.h doc-proof.h proofcheck.h \
+  options.h tableau.h clock.h closure.h table.h partition.h ras.h \
+  analyze.h graph.h cnf.h hasharray.h renaming.h resolution.h
+unify.o: unify.c unify.h term.h symbol.h list.h memory.h misc.h \
+  stringsx.h stack.h context.h subst.h
+vector.o: vector.c vector.h misc.h
diff --git a/test/spass/AUTHORS b/test/spass/AUTHORS
new file mode 100644
index 0000000000000000000000000000000000000000..c373ede86cf15698408caf6efce3729d9d4c90ba
--- /dev/null
+++ b/test/spass/AUTHORS
@@ -0,0 +1,23 @@
+Current:
+========
+
+Christoph Weidenbach		<weidenb@mpi-sb.mpg.de>
+Uwe Brahm			<brahm@mpi-sb.mpg.de>
+Thomas Hillenbrand		<hillen@mpi-sb.mpg.de>
+Dalibor Topic			<topic@mpi-sb.mpg.de>
+
+
+Former:
+=======
+
+Bijan Afshordel			<afshorde@mpi-sb.mpg.de>
+Christof Brinker		<chbr@mpi-sb.mpg.de>
+Christian Cohrs			<cohrs@mpi-sb.mpg.de>
+Thorsten Engel			<engel@mpi-sb.mpg.de>
+Bernd Gaede			<gaede@mpi-sb.mpg.de>
+Peter Graf			<graf@mpi-sb.mpg.de>
+Georg Jung			<gjung@mpi-sb.mpg.de>
+Christoph Meyer			<meyer@mpi-sb.mpg.de>
+Georg Rock			<rock@mpi-sb.mpg.de>
+Christian Theobalt		<theobalt@mpi-sb.mpg.de>
+
diff --git a/test/spass/COPYING b/test/spass/COPYING
new file mode 100644
index 0000000000000000000000000000000000000000..eeb586b392a5a7dc63d64ba697374ea37e6e122a
--- /dev/null
+++ b/test/spass/COPYING
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    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.
+
+    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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/test/spass/LICENSE.TXT b/test/spass/LICENSE.TXT
new file mode 100644
index 0000000000000000000000000000000000000000..72712689ff8bdc9507ca4549b6d97e6ee70b835b
--- /dev/null
+++ b/test/spass/LICENSE.TXT
@@ -0,0 +1 @@
+see the file "COPYING"
diff --git a/test/spass/Makefile b/test/spass/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..b96477070f052ee02492757886fe37ee11c570e5
--- /dev/null
+++ b/test/spass/Makefile
@@ -0,0 +1,34 @@
+CC=../../ccomp 
+CFLAGS=-stdlib ../../runtime -dparse -dclight -dasm -fstruct-passing -fstruct-assign
+
+SRCS=analyze.c clause.c clock.c closure.c cnf.c component.c                 \
+  condensing.c context.c defs.c dfgparser.c dfgscanner.c doc-proof.c        \
+  flags.c foldfg.c graph.c hash.c hasharray.c iaparser.c iascanner.c        \
+  kbo.c list.c memory.c misc.c options.c order.c partition.c                \
+  proofcheck.c renaming.c resolution.c rpos.c rules-inf.c rules-red.c       \
+  rules-sort.c rules-split.c rules-ur.c search.c sharing.c sort.c st.c      \
+  stack.c strings.c subst.c subsumption.c symbol.c table.c tableau.c        \
+  term.c terminator.c top.c unify.c vector.c
+
+all: spass
+
+spass: $(SRCS:.c=.o)
+	$(CC) $(CFLAGS) -o spass $(SRCS:.c=.o)
+
+clean:
+	rm -f spass
+	rm -f *.o *.s *.parsed.c *.light.c
+
+test:
+	./spass small_problem.dfg | grep 'Proof found'
+
+TIME=xtime -o /dev/null     # Xavier's hack
+#TIME=time >/dev/null       # Otherwise
+
+bench:
+	$(TIME) ./spass problem.dfg
+
+depend:
+	gcc -MM $(SRCS) > .depend
+
+include .depend
diff --git a/test/spass/Makefile.bak b/test/spass/Makefile.bak
new file mode 100644
index 0000000000000000000000000000000000000000..320f6221bff8f98d6d05e4eb0177439042b5e7c0
--- /dev/null
+++ b/test/spass/Makefile.bak
@@ -0,0 +1,13 @@
+LEVEL = ../../..
+PROG = SPASS
+
+CPPFLAGS = -DCLOCK_NO_TIMING -fno-strict-aliasing -w
+LDFLAGS  = -lm
+
+ifdef SMALL_PROBLEM_SIZE
+RUN_OPTIONS="$(PROJ_SRC_DIR)/small_problem.dfg"
+else
+RUN_OPTIONS="$(PROJ_SRC_DIR)/problem.dfg"
+endif
+
+include ../../Makefile.multisrc
diff --git a/test/spass/README b/test/spass/README
new file mode 100644
index 0000000000000000000000000000000000000000..efdfb84f1ebd35beec890e64367048cfe74f5528
--- /dev/null
+++ b/test/spass/README
@@ -0,0 +1,96 @@
+				Welcome to SPASS!
+				=================
+
+This is the generic README file for all SPASS distributions, so your downloaded
+package may only contain a subset of what is described here.
+
+
+				Important Files
+				===============
+
+AUTHORS		all authors that contributed to SPASS
+
+INSTALLATION 	for a guide to install the prover, man pages,
+             	tools etc.; by default binaries are installed
+		in /usr/local/bin and man-pages in /usr/local/man;
+		use the prefix option of make install for a different
+		path
+	
+COPYING      	for the licence agreement that you certify by
+             	installation, its the GNU GENERAL PUBLIC LICENSE, Version 2
+
+VERSIONHISTORY	changes starting from version 1.0.0
+
+README		is this file
+
+
+
+
+				Programs
+				========
+
+The distribution contains the following programs. Most
+of them give you a brief description if they are called
+without arguments. Most of the programs come with man-pages. 
+
+SPASS		is our prover for first-order logic with equality.
+
+FLOTTER		translates first-order formulae into clauses; its
+ 		incorporated in SPASS and hence now only a link to
+		SPASS.
+
+pcs		is our proof checker. NOTE that in its default settings
+		pcs needs an installation of otter for proof checking.
+		You can also employ SPASS itself for this purpose by the
+		-o option.
+
+pgen		generates out of a SPASS proof file all subtasks needed
+		to guarantee the correctness of the proof.
+
+dfg2otter	translates DFG-syntax input  files into otter input files,
+		without any settings commands.
+
+dfg2otter.pl	has the same functionality than dfg2otter but adds specific
+		settings that are useful if otter is employd as a proof checker
+		for SPASS.
+
+dfg2tptp	translates DFG-syntax input  files into TPTP input files.
+
+
+dfg2ascii  	provides an ASCII pretty print of DFG-syntax input files
+
+
+				Documentation
+				=============
+
+Besides the man pages, in the directory doc you'll find a description
+of our input syntax (spass-input-syntax.pdf), a small tutorial (tutorial.pdf)
+that is just a print out of our tutorial web page and the complete
+theory of SPASS (handbook-spass.pdf). Furthermore, there is a FAQ 
+database (faq.txt).
+
+
+				Examples
+				========
+
+In the examples directory you'll find some small examples. Further
+example collections can be downloaded from the SPASS homepage. By
+convention, files ending in ".dfg" are formula files and files ending 
+in ".cnf" are files containing clauses.
+
+				
+				    WWW
+				    ===
+
+Consider the SPASS homepage at 
+
+			http://spass.mpi-sb.mpg.de/
+
+for recent developments, downloads etc.
+
+
+
+
+
+have SPASS
+  Christoph Weidenbach
\ No newline at end of file
diff --git a/test/spass/VERSIONHISTORY b/test/spass/VERSIONHISTORY
new file mode 100644
index 0000000000000000000000000000000000000000..448870ccde1710c01f49be6c89950e9426cbf786
--- /dev/null
+++ b/test/spass/VERSIONHISTORY
@@ -0,0 +1,135 @@
+Version: 1.0.1
+
+	- Fixed a bug in the atom definition support where it could happen
+          that variable dependencies between the atom definition and formulae
+          outside the definition are discarded.
+
+	- Fixed a bug in the renaming module, where in some cases a renaming
+	  with non-zero benefit was not performed.
+
+Version: 1.0.2
+
+	- Fixed inconsistencies between the DFG proof format description in 
+	  dfgsyntax.ps and the actual implementation. Proof checking is more 
+	  more liberal, because the empty clause needs not to have the highest
+	  clause number.
+
+Version: 1.0.3
+
+	- Sharpend renaming; it now potentially produces fewer clauses.
+
+Version: 1.0.4
+
+	- Changed some clause generation functions such that sequentially
+	  applying FLOTTER, SPASS and just applying SPASS result in the
+	  very same clause sets.
+
+	- Added the new tool dfg2dfg that supports transformations into
+	  monadic clause classes and their further approximations.
+
+Version: 1.0.5
+
+	- Improved SPASS man pages: In particular, we added further detailed 
+	  explanations of inference rule flags and soft typing flags.
+
+	- Significantly improved modularity of the code by making the flagstore
+	  object part of the proof search object; so there is no global flagstore
+	  around anymore. These changes touched nearly all modules.
+
+	- Changed certain clause generation procedures such that now applying SPASS
+	  directly to a formula or subsequent application of FLOTTER and SPASS produce
+	  exactly the same ordering of a clause set (literlas). Since the behaviour of
+	  SPASS is not independant from initial clause/literal orderings the changes
+	  make SPASS results a little more robust/more predictable.
+	  As all code was touched, we also included a code style review (comments,
+	  prototypes, ...).
+
+	- Flag values given to SPASS are now checked and rejected if out of range.
+
+Version: 1.0.6
+
+	- Strengthened prototyping of functions in particular in the case of function
+	  arguments. This resulted in specialized extra functions.
+	  
+	- Improved printing efficiency by replacing (f)printf calls with (f)puts calls
+	  whenever possible.
+
+	- Removed the modul global precedence variable of the symbol modul and replaced
+	  it by argument passing. The precedence is now stored in the proofsearch structure.
+	  This affected huge parts of the SPASS code.
+
+	- Adjusted comments and code layout.
+
+	- Strengthened warnings for the gcc compiler.
+
+	- Increased usage of the string module.
+
+
+Version: 2.0.0
+
+	- Corrections to spellings, documentation.
+
+	- Added handbooks for SPASS and dfg2dfg.
+
+	- Added contextual rewriting.
+
+	- Added semantic tautology check.
+
+	- Fixed bugs in CNF translation: Renaming, Equation elimination rules.
+
+	- Improved splitting clause selection on the basis of reduction potential.
+
+	- Improved robustness of initial clause list ordering.
+
+	- Added the terminator module.
+
+	- Extended formula definition detection/expansion to so called guarded definitions.
+
+	- Improved determination of initial precedence such that as many as possible
+	  equations in the input clause list can be oriented.
+
+	- Added mainloop without complete interreduction.
+
+	- Developed PROOFSEARCH data type enabling a modularization of the SPASS
+	  source code on search engine level, such that several proof attempts can
+	  now be run completely independantly at the same time within SPASS.
+
+	- Moved GUI to Qt 3.0. The GUI now also includes dfg2dfg and new even more
+	  user friendly layout. The GUI runs on any platform where SPASS and Qt are
+	  available.
+
+Version: 2.1
+
+	- Fixed a bug in the definition module. Formulae were not normalized before
+	  application of the procedure, leading to wrong matchings of variables.
+
+	- Fixed a bug in the flag module. The subproof flagstore settings were not
+	  complete: ordering flag and the weight flags were missing.
+
+	- Fixed a bug in dfgparser.y, where a missing semicolon with
+	  bison version 1.75 now caused an error.
+
+	- Fixed a bug in cnf.c where the formula "equiv(false,false)" was
+	  not properly treated in function cnf_RemoveTrivialAtoms.
+
+	- Fixed a bug in symbol_LowerSignature where capital 'A's and 'Z's were not
+	  prefixed by a lowercase 'ss' due to their exclusion in the condition. This
+	  caused problems in the result of dfg2tptp applied to dfg input files with
+	  uppercase symbols starting with an 'A' or 'Z'.
+
+	- Now dfg2otter negates conjecture formulae of the SPASS input file
+	  before printing the Otter usable list.
+
+	- Added man pages for dfg2ascii, dfg2otter and dfg2tptp.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/spass/analyze.c b/test/spass/analyze.c
new file mode 100644
index 0000000000000000000000000000000000000000..dd47d0d938c41dd51f0124208048f3c659f813b4
--- /dev/null
+++ b/test/spass/analyze.c
@@ -0,0 +1,774 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                ANALYSIS OF CLAUSE SETS                 * */
+/* *                                                        * */
+/* *  $Module:   ANALYZE                                    * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include <stdio.h>
+
+#include "analyze.h"
+
+static LIST ana_CalculatePredicatePrecedence(LIST, LIST);
+static LIST ana_CalculateFunctionPrecedence(LIST, LIST, FLAGSTORE);
+
+/**************************************************************/
+/* Global Variables                                           */
+/**************************************************************/
+
+LIST ana_FINITEMONADICPREDICATES;  /* List of monadic predicates with finite extension */
+
+BOOL ana_EQUATIONS;                /* Problem contains any equations at all */
+static BOOL ana_PEQUATIONS;        /* Problem contains positive equations */
+static BOOL ana_NEQUATIONS;        /* Problem contains negative equations */
+static BOOL ana_FUNCTIONS;         /* Problem contains non-constant function symbols */
+static BOOL ana_PROP;              /* Problem contains propositional variables */
+static BOOL ana_GROUND;            /* Problem contains non-propositional, non-equational ground atoms */
+static BOOL ana_NONUNIT;           /* Problem contains non-unit clauses */
+static BOOL ana_MONADIC;           /* Problem contains non-ground monadic predicates */
+static BOOL ana_NONMONADIC;        /* Problem contains non-ground n-place predicates, n>1, not equality */
+BOOL ana_SORTRES;                  /* Problem contains literal not(S(x)) for some S */
+BOOL ana_USORTRES;                 /* Problem contains literal not(S(t)) for some S */
+static BOOL ana_FINDOMAIN;         /* Problem contains clause implying a finite domain */
+static BOOL ana_NONTRIVDOMAIN;     /* Problem contains clause implying a domain of size greater one */
+static BOOL ana_CONGROUND;         /* Conjecture is ground */
+
+static BOOL ana_PUREEQUATIONAL;    /* Problem is purely equational */
+static BOOL ana_PUREPROPOSITIONAL; /* Problem is purely propositional */
+
+BOOL ana_SORTDECEQUATIONS;         /* True if all positive equations are sort decreasing with respect to
+                                      the static sort theory contained in the problem */
+static BOOL ana_SORTMANYEQUATIONS;  /* True if all positive equations have the
+				       same sort on left and right hand side with
+				       respect to the static sort theory
+				       contained in the problem */
+
+static NAT  ana_AXIOMCLAUSES;      /* Number of axiom clauses */
+static NAT  ana_CONCLAUSES;        /* Number of conjecture clauses */
+static NAT  ana_NONHORNCLAUSES;    /* Number of Non-Horn clauses */
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+void ana_AnalyzeProblem(PROOFSEARCH Search, LIST Clauses)
+/**************************************************************
+  INPUT:   A proofsearch object and a list of clauses.
+  RETURNS: Void.
+  EFFECT:  Analyzes the clauses and sets the analyze variables.
+           Recomputes the weight for the clauses.
+	   <Search> is modified according to clauses: non trivial domain number
+	   is set
+***************************************************************/
+{
+  CLAUSE Clause;
+
+  ana_EQUATIONS       = FALSE;  
+  ana_PEQUATIONS      = FALSE;             /* Defaults for properties */
+  ana_NEQUATIONS      = FALSE; 
+  ana_FUNCTIONS       = FALSE;
+  ana_FINDOMAIN       = FALSE;
+  ana_NONTRIVDOMAIN   = FALSE;
+  ana_MONADIC         = FALSE;
+  ana_NONMONADIC      = FALSE;
+  ana_PROP            = FALSE;
+  ana_GROUND          = FALSE;
+  ana_SORTRES         = FALSE;
+  ana_USORTRES        = FALSE;
+  ana_NONUNIT         = FALSE;
+  ana_CONGROUND       = TRUE;
+
+  ana_AXIOMCLAUSES    = 0; 
+  ana_CONCLAUSES      = 0;
+  ana_NONHORNCLAUSES  = 0;
+
+  list_Delete(ana_FINITEMONADICPREDICATES);
+  ana_FINITEMONADICPREDICATES = list_Nil();
+
+  if (list_Empty(Clauses))
+    return;
+
+  ana_FINITEMONADICPREDICATES = clause_FiniteMonadicPredicates(Clauses);
+
+  while (!list_Empty(Clauses)) {
+    Clause = (CLAUSE)list_Car(Clauses);
+    clause_UpdateWeight(Clause, prfs_Store(Search));
+
+    if (clause_GetFlag(Clause,CONCLAUSE))
+      ana_CONCLAUSES++;
+    else
+      ana_AXIOMCLAUSES++;
+
+    if (clause_NumOfSuccLits(Clause) > 1)
+      ana_NONHORNCLAUSES++;
+
+    if (ana_CONGROUND && clause_GetFlag(Clause,CONCLAUSE) &&
+	clause_MaxVar(Clause) != symbol_GetInitialStandardVarCounter())
+      ana_CONGROUND = FALSE;
+    if (!ana_PEQUATIONS && clause_ContainsPositiveEquations(Clause)) {
+      ana_PEQUATIONS = TRUE;
+    }
+    if (!ana_NEQUATIONS && clause_ContainsNegativeEquations(Clause)) {
+      ana_NEQUATIONS = TRUE;
+    }
+    if (!ana_MONADIC || !ana_NONMONADIC || !ana_PROP || !ana_GROUND)
+      clause_ContainsFolAtom(Clause,&ana_PROP,&ana_GROUND,&ana_MONADIC,&ana_NONMONADIC);
+
+    if (!ana_FUNCTIONS && clause_ContainsFunctions(Clause)) {
+      ana_FUNCTIONS = TRUE;
+    }
+    if (!ana_FINDOMAIN && clause_ImpliesFiniteDomain(Clause)) {
+      ana_FINDOMAIN = TRUE;
+    }
+    if (!ana_NONTRIVDOMAIN && clause_ImpliesNonTrivialDomain(Clause)) {
+      prfs_SetNonTrivClauseNumber(Search, clause_Number(Clause));
+      ana_NONTRIVDOMAIN =  TRUE;
+    }
+    if (!ana_NONUNIT && clause_Length(Clause) > 1) {
+      ana_NONUNIT = TRUE;
+    }
+    if (!ana_SORTRES || !ana_USORTRES) 
+      clause_ContainsSortRestriction(Clause,&ana_SORTRES,&ana_USORTRES);
+    
+    Clauses = list_Cdr(Clauses);
+  }
+
+  ana_PUREEQUATIONAL    = ((ana_PEQUATIONS || ana_NEQUATIONS) && !ana_MONADIC &&
+			   !ana_NONMONADIC && !ana_PROP && !ana_GROUND);
+  ana_EQUATIONS         = (ana_PEQUATIONS || ana_NEQUATIONS);
+  ana_PUREPROPOSITIONAL = (!ana_PEQUATIONS && !ana_NEQUATIONS &&!ana_MONADIC &&
+			   !ana_NONMONADIC && ana_PROP);
+}
+
+
+void ana_AnalyzeSortStructure(LIST Clauses, FLAGSTORE Flags,
+			      PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A list of clauses, a flag store and a precedence.
+  RETURNS: Nothing.
+  EFFECT:  The sort structure with respect to equations is analyzed.
+           It is detected whether all equations are many sorted or
+	   sort decreasing.
+***************************************************************/
+{
+  if (ana_PEQUATIONS && ana_SORTRES) {
+    STR Result;
+    Result                = sort_AnalyzeSortStructure(Clauses,Flags,Precedence);
+    ana_SORTMANYEQUATIONS = (Result == SORTEQMANY);
+    ana_SORTDECEQUATIONS  = (Result == SORTEQMANY || Result == SORTEQDECR);
+  }
+}
+
+
+void ana_Print(FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A flag store and a precedence.
+  RETURNS: Nothing.
+  EFFECT:  The results of an analysis stored in the module variables
+           is printed to stdout.
+***************************************************************/
+{
+  const char* Horn;
+
+  if (ana_NONHORNCLAUSES == 0)
+    Horn = "Horn";
+  else
+    Horn = "Non-Horn";
+  
+  if (ana_MONADIC && !ana_NONMONADIC) {
+    printf("\n This is a monadic %s problem",Horn);
+    if (ana_PEQUATIONS || ana_NEQUATIONS)
+      fputs(" with equality.", stdout);
+    else
+      fputs(" without equality.", stdout);
+  }
+  else
+    if (ana_PEQUATIONS || ana_NEQUATIONS) {
+      if (ana_NONMONADIC || ana_MONADIC || ana_PROP)
+	printf("\n This is a first-order %s problem containing equality.",Horn);
+      else
+	if (ana_NONUNIT)
+	  printf("\n This is a pure equality %s problem.",Horn);
+	else
+	  fputs("\n This is a unit equality problem.", stdout);
+    }
+    else
+      if (ana_NONMONADIC || ana_MONADIC)
+	printf("\n This is a first-order %s problem without equality.",Horn);
+
+  if (ana_PUREPROPOSITIONAL)
+    printf("\n This is a propositional %s problem.",Horn);
+  else
+    if (ana_FINDOMAIN || !ana_FUNCTIONS) {
+      fputs("\n This is a problem that has, if any, a finite domain model.",
+	    stdout);
+      if (ana_FINDOMAIN)
+	fputs("\n There is a finite domain clause.", stdout);
+      if (!ana_FUNCTIONS)
+	fputs("\n There are no function symbols.", stdout);
+    }
+
+  if (ana_NONTRIVDOMAIN)
+    fputs("\n This is a problem that has, if any, a non-trivial domain model.",
+	  stdout);
+      
+  
+  if (ana_SORTRES) {
+    fputs("\n This is a problem that contains sort information.", stdout);
+    if (ana_PEQUATIONS) {
+      if (ana_SORTMANYEQUATIONS)
+	fputs("\n All equations are many sorted.", stdout);
+      else {
+	if (ana_SORTDECEQUATIONS)
+	  fputs("\n All equations are sort-decreasing.", stdout);
+      }
+    }
+  }
+
+  if (ana_CONCLAUSES > 0 && ana_CONGROUND && !ana_PUREPROPOSITIONAL)
+    fputs("\n The conjecture is ground.", stdout);
+
+  if (!list_Empty(ana_FINITEMONADICPREDICATES)) {
+    LIST Scan;
+    fputs("\n The following monadic predicates have finite extensions: ", stdout);
+    for (Scan=ana_FINITEMONADICPREDICATES;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+      symbol_Print((SYMBOL)list_Car(Scan));
+      if (!list_Empty(list_Cdr(Scan)))
+	fputs(", ", stdout);
+    }
+    putchar('.');
+  }
+
+  printf("\n Axiom clauses: %d Conjecture clauses: %d",ana_AXIOMCLAUSES,ana_CONCLAUSES);
+
+  flag_PrintInferenceRules(Flags);
+  flag_PrintReductionRules(Flags);
+  fputs("\n Extras    : ", stdout);
+  if (flag_GetFlagValue(Flags, flag_SATINPUT))
+    fputs("Input Saturation, ", stdout);
+  else
+    fputs("No Input Saturation, ", stdout);
+  if (flag_GetFlagValue(Flags, flag_SELECT) == flag_SELECTOFF)
+    fputs("No Selection, ", stdout);
+  else
+    if (flag_GetFlagValue(Flags, flag_SELECT) == flag_SELECTIFSEVERALMAXIMAL)
+      fputs("Dynamic Selection, ", stdout);
+    else
+      fputs("Always Selection, ", stdout);
+  if (flag_GetFlagValue(Flags, flag_SPLITS) == flag_SPLITSUNLIMITED)
+    fputs("Full Splitting, ", stdout);
+  else
+    if (flag_GetFlagValue(Flags, flag_SPLITS) == flag_SPLITSOFF)
+      fputs("No Splitting, ", stdout);
+    else
+      printf("Maximum of %d Splits, ",flag_GetFlagValue(Flags, flag_SPLITS));
+  if (flag_GetFlagValue(Flags, flag_FULLRED))
+    fputs("Full Reduction, ", stdout);
+  else
+    fputs("Lazy Reduction, ", stdout);
+  printf(" Ratio: %d, FuncWeight: %d, VarWeight: %d",
+	 flag_GetFlagValue(Flags, flag_WDRATIO),
+	 flag_GetFlagValue(Flags, flag_FUNCWEIGHT),
+	 flag_GetFlagValue(Flags, flag_VARWEIGHT));
+  fputs("\n Precedence: ", stdout);
+  fol_PrintPrecedence(Precedence);
+  fputs("\n Ordering  : ", stdout);
+  fputs(flag_GetFlagValue(Flags, flag_ORD) == flag_ORDKBO ? "KBO" : "RPOS",
+	stdout);
+}
+
+
+void ana_AutoConfiguration(LIST Clauses, FLAGSTORE Flags,
+			   PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A list of clauses, a flag store and a precedence.
+  RETURNS: Nothing.
+  EFFECT:  Based on the values of the ana analysis module, an appropriate
+           complete configuration of inference, reduction rules and other
+	   settings is established.
+***************************************************************/
+{
+  LIST Scan, Functions, Predicates, Constants;
+
+  Functions  = symbol_GetAllFunctions();
+  Predicates = fol_GetNonFOLPredicates();
+
+  /* Set precedence */
+  Predicates = ana_CalculatePredicatePrecedence(Predicates, Clauses);
+  Functions  = ana_CalculateFunctionPrecedence(Functions, Clauses, Flags);
+  Constants  = list_Nil();
+
+  for (Scan=Functions; !list_Empty(Scan); Scan=list_Cdr(Scan))
+    if (symbol_IsConstant((SYMBOL)list_Car(Scan)))
+      Constants = list_Cons(list_Car(Scan),Constants);
+  Functions = list_NPointerDifference(Functions,Constants);
+  Constants = list_NReverse(Constants);
+
+  for ( ; !list_Empty(Functions); Functions = list_Pop(Functions))
+    symbol_SetIncreasedOrdering(Precedence, (SYMBOL)list_Car(Functions));
+  /* Predicates < Functions */
+  for ( ; !list_Empty(Predicates); Predicates = list_Pop(Predicates))
+    symbol_SetIncreasedOrdering(Precedence, (SYMBOL)list_Car(Predicates));
+  /* Constants < Predicates */
+  /* Predicates < Functions */
+  for ( ; !list_Empty(Constants); Constants = list_Pop(Constants))
+    symbol_SetIncreasedOrdering(Precedence, (SYMBOL)list_Car(Constants));
+
+  flag_ClearInferenceRules(Flags);
+  flag_ClearReductionRules(Flags);
+
+  flag_SetFlagValue(Flags, flag_ROBV,    flag_ROBVON);
+  flag_SetFlagValue(Flags, flag_RTAUT,   flag_RTAUTSYNTACTIC);
+  flag_SetFlagValue(Flags, flag_RFSUB,   flag_RFSUBON);
+  flag_SetFlagValue(Flags, flag_RBSUB,   flag_RBSUBON);
+  flag_SetFlagValue(Flags, flag_RFMRR,   flag_RFMRRON);
+  flag_SetFlagValue(Flags, flag_RBMRR,   flag_RBMRRON);
+  flag_SetFlagValue(Flags, flag_RUNC,    flag_RUNCON);
+  flag_SetFlagValue(Flags, flag_FULLRED, flag_FULLREDON);
+  /*flag_SetFlagValue(Flags, flag_FUNCWEIGHT,1);
+  flag_SetFlagValue(Flags, flag_VARWEIGHT,1);*/
+  flag_SetFlagValue(Flags, flag_WDRATIO,5);
+
+  if (ana_NEQUATIONS) {
+    flag_SetFlagValue(Flags, flag_IEQR, flag_EQUALITYRESOLUTIONON);
+    if (ana_NONUNIT) {
+      if (ana_NONTRIVDOMAIN)
+	flag_SetFlagValue(Flags, flag_RAED, flag_RAEDPOTUNSOUND);
+      else
+	flag_SetFlagValue(Flags, flag_RAED, flag_RAEDSOUND);
+    }
+  }
+
+  if (ana_PEQUATIONS) {
+    flag_SetFlagValue(Flags, flag_ISPR, flag_SUPERPOSITIONRIGHTON);
+    flag_SetFlagValue(Flags, flag_ISPL, flag_SUPERPOSITIONLEFTON);
+    if (ana_NONHORNCLAUSES > 0)
+      flag_SetFlagValue(Flags, flag_IEQF, flag_EQUALITYFACTORINGON);
+    if (ana_NONUNIT) 
+      flag_SetFlagValue(Flags, flag_RCON, flag_RCONON);
+    flag_SetFlagValue(Flags, flag_RFREW, flag_RFREWON);
+    flag_SetFlagValue(Flags, flag_RBREW, flag_RBREWON);
+    flag_SetFlagValue(Flags, flag_RFCRW, flag_RFCRWOFF); /* Here we could activate contextual rewriting */
+    flag_SetFlagValue(Flags, flag_RBCRW, flag_RBCRWOFF);
+  }
+  
+  if (ana_SORTRES) {
+    flag_SetFlagValue(Flags, flag_SORTS, flag_SORTSMONADICWITHVARIABLE);
+    flag_SetFlagValue(Flags, flag_IEMS,  flag_EMPTYSORTON);
+    flag_SetFlagValue(Flags, flag_ISOR,  flag_SORTRESOLUTIONON);
+    flag_SetFlagValue(Flags, flag_RSSI, flag_RSSION);
+    if (!ana_PEQUATIONS || ana_SORTMANYEQUATIONS)
+      flag_SetFlagValue(Flags, flag_RSST, flag_RSSTON);
+  }
+  else
+    flag_SetFlagValue(Flags, flag_SORTS, flag_SORTSOFF);
+
+  if (ana_MONADIC || ana_NONMONADIC) { /* Problem contains real predicates */
+    flag_SetFlagValue(Flags, flag_IORE, flag_ORDEREDRESOLUTIONNOEQUATIONS);
+    if (ana_NONHORNCLAUSES > 0)
+      flag_SetFlagValue(Flags, flag_IOFC, flag_FACTORINGONLYRIGHT);
+    if (ana_NONUNIT) 
+      flag_SetFlagValue(Flags, flag_RCON, flag_RCONON);
+  }
+
+
+  if (!ana_FUNCTIONS)
+    flag_SetFlagValue(Flags, flag_SELECT, flag_SELECTALWAYS);
+  else
+    if (ana_NONUNIT)
+      flag_SetFlagValue(Flags, flag_SELECT, flag_SELECTIFSEVERALMAXIMAL);
+    else
+      flag_SetFlagValue(Flags, flag_SELECT, flag_SELECTOFF);
+
+  if (ana_CONCLAUSES < ana_AXIOMCLAUSES || (ana_CONGROUND && !ana_PUREPROPOSITIONAL))
+    flag_SetFlagValue(Flags, flag_SATINPUT, flag_SATINPUTON);
+  else
+    flag_SetFlagValue(Flags, flag_SATINPUT, flag_SATINPUTOFF);
+
+  if (ana_NONHORNCLAUSES > 0)
+    flag_SetFlagValue(Flags, flag_SPLITS, flag_SPLITSUNLIMITED);
+  else
+    flag_SetFlagValue(Flags, flag_SPLITS, flag_SPLITSOFF);
+}
+
+
+void ana_ExploitSortAnalysis(FLAGSTORE Flags)
+/**************************************************************
+  INPUT:   A flag store.
+  EFFECT:  If all equations are many sorted and or no positive
+           equations occur at all and the problem contains sort
+	   information, static soft typing is activated.
+***************************************************************/
+{
+  if (ana_SORTRES && (!ana_PEQUATIONS || ana_SORTMANYEQUATIONS))
+    flag_SetFlagValue(Flags, flag_RSST, flag_RSSTON);
+}
+
+
+static LIST ana_CalculatePredicatePrecedence(LIST Predicates, LIST Clauses)
+/**************************************************************
+  INPUT:   A list of predicates and a list of clauses.
+  RETURNS: A list of predicate symbols, which should be used
+           for setting the symbol precedence. The list is sorted
+           in descending order, that means predicates with highest
+           precedence come first.
+  EFFECT:  Analyze the clause list to build a directed graph G where
+           the predicates are vertices. There's an edge (P,Q) in
+           G iff a clause exists where P is a negative literal
+           and Q is a positive literal and P != Q. Apply DFS to
+           find the strongly connected components of this graph.
+	   The <Predicates> list is deleted.
+  CAUTION: The predicate list must contain ALL predicates
+           occurring in the clause list!
+***************************************************************/
+{
+  GRAPH  graph;
+  LIST   result, scan;
+  int    i, j;
+  NAT    count;
+  SYMBOL s;
+
+  /* clause_ListPrint(Clauses); DBG */
+
+  if (list_Empty(Predicates)) {
+    return Predicates;
+  }
+
+  graph = graph_Create();
+
+  /* First create the nodes: one node for every predicate symbol. */
+  for ( ; !list_Empty(Predicates); Predicates = list_Pop(Predicates))
+    graph_AddNode(graph, symbol_Index((SYMBOL)list_Car(Predicates)));
+
+  /* Now scan the clause clause list to create the edges */
+  /* An edge (P,Q) means P is smaller than Q */
+  for (scan = Clauses; !list_Empty(scan); scan = list_Cdr(scan)) {
+    CLAUSE c = list_Car(scan);
+
+    for (i = clause_FirstLitIndex(); i < clause_FirstSuccedentLitIndex(c); i++) {
+      SYMBOL negPred = term_TopSymbol(clause_GetLiteralAtom(c, i));
+      if (!symbol_Equal(negPred, fol_Equality())) { /* negative predicate */
+	for (j = clause_FirstSuccedentLitIndex(c); j < clause_Length(c); j++) {
+	  SYMBOL posPred = term_TopSymbol(clause_GetLiteralAtom(c, j));
+	  if (!symbol_Equal(posPred, fol_Equality()) && /* positive predicate */
+	      negPred != posPred) {  /* No self loops! */
+	    graph_AddEdge(graph_GetNode(graph, symbol_Index(negPred)),
+			  graph_GetNode(graph, symbol_Index(posPred)));
+	  }
+	}
+      }
+    }
+  }
+
+  /* graph_Print(graph); fflush(stdout); DBG */
+
+  /* Calculate the strongly connected components of the graph */
+  count = graph_StronglyConnectedComponents(graph);
+
+  /* Now create the precedence list by scanning the nodes.        */
+  /* If there's a link between two strongly connected components  */
+  /* c1 and c2 then component_num(c1) > component_num(c2), so the */
+  /* following code creates a valid precedence list in descending */
+  /* order.                                                       */
+  result = list_Nil();
+  for (i = count - 1; i >= 0; i--) {
+    for (scan = graph_Nodes(graph); !list_Empty(scan); scan = list_Cdr(scan)) {
+      GRAPHNODE n = list_Car(scan);
+      if (graph_NodeCompNum(n) == i) {
+	/* The symbol represented by the node <<n> belongs to component <i> */
+	s = symbol_GetSigSymbol(graph_NodeNumber(n));
+	result = list_Cons((POINTER)s, result);
+      }
+    }
+  }
+
+  /* putchar('\n');
+     for (scan = result; !list_Empty(scan); scan = list_Cdr(scan)) {
+     s = (SYMBOL) list_Car(scan);
+     symbol_Print(s);
+     putchar(' ');
+     }
+     putchar('\n'); fflush(stdout); DBG */
+
+  graph_Delete(graph);
+
+  return result;
+}
+
+
+/* We use the node info to store the degree of the node */
+static __inline__ NAT ana_NodeDegree(GRAPHNODE Node)
+{
+  return (NAT)graph_NodeInfo(Node);
+}
+
+
+static __inline__ void ana_IncNodeDegree(GRAPHNODE Node)
+{
+  graph_NodeSetInfo(Node, (POINTER)(ana_NodeDegree(Node)+1));
+}
+
+static BOOL ana_NodeGreater(GRAPHNODE N1, GRAPHNODE N2)
+/**************************************************************
+  INPUT:   Two graph nodes.
+  RETURNS: TRUE, if N1 is greater than N2.
+  EFFECT:  This function is used to sort the node list
+           of the graph in ana_CalculateFunctionPrecedence.
+***************************************************************/
+{
+  return (symbol_Arity(symbol_GetSigSymbol(graph_NodeNumber(N1))) >
+	  symbol_Arity(symbol_GetSigSymbol(graph_NodeNumber(N2))));
+}
+
+
+static BOOL ana_BidirectionalDistributivity(LIST SymbolPairs)
+/**************************************************************
+  INPUT:   A list of symbol pairs defining distributivity.
+  RETURNS: TRUE, if the list contains two pairs (s1, s2) and (s2, s1)
+           FALSE otherwise.
+  EFFECT:  This function is used to detect symbols that are distributive
+           in both directions, logical OR and AND for example.
+***************************************************************/
+{
+  LIST scan, actPair, nextPair;
+
+  for ( ; !list_Empty(SymbolPairs); SymbolPairs = list_Cdr(SymbolPairs)) {
+    actPair = list_Car(SymbolPairs);
+    /* If actPair = (s1, s2), check whether there's a pair (s2, s1) in list */
+    for (scan = list_Cdr(SymbolPairs); !list_Empty(scan); scan = list_Cdr(scan)) {
+      nextPair = list_Car(scan);
+      if (symbol_Equal((SYMBOL)list_PairFirst(actPair),(SYMBOL)list_PairSecond(nextPair)) &&
+	  symbol_Equal((SYMBOL)list_PairSecond(actPair),(SYMBOL)list_PairFirst(nextPair)))
+	return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+
+static LIST ana_CalculateFunctionPrecedence(LIST Functions, LIST Clauses,
+					    FLAGSTORE Flags)
+/**************************************************************
+  INPUT:   A list of functions, a list of clauses and 
+           a flag store.
+  RETURNS: A list of function symbols, which should be used
+           for setting the symbol precedence. The list is sorted
+           in descending order, that means function with highest
+           precedence come first.
+  EFFECT:  Analyzes the clauses to build a directed graph G with
+           function symbol as nodes. An edge (f,g) or in G means
+           f should have lower precedence than g.
+           An edge (f,g) or (g,f) is created if there's an equation
+           equal(f(...), g(...)) in the clause list.
+	   The direction of the edge depends on the degree of the
+           nodes and the symbol arity.
+	   Then find the strongly connected components of this
+           graph.
+           The "Ordering" flag will be set in the flag store.
+  CAUTION: The value of "ana_PEQUATIONS" must be up to date.
+***************************************************************/
+{
+  GRAPH     graph;
+  GRAPHNODE n1, n2;
+  LIST      result, scan, scan2, distrPairs;
+  NAT       i, j;
+  SYMBOL    s, Add, Mult;
+
+  if (list_Empty(Functions))
+    return Functions;   /* Problem contains no functions */
+  else if (!ana_PEQUATIONS) {
+    Functions = list_NumberSort(Functions, (NAT (*)(POINTER)) symbol_PositiveArity);
+    return Functions;
+  }
+
+  graph = graph_Create();
+  /* First create the nodes: one node for every function symbol. */
+  for (; !list_Empty(Functions); Functions = list_Pop(Functions))
+    graph_AddNode(graph, symbol_Index((SYMBOL)list_Car(Functions)));
+
+  /* Now sort the node list wrt descending symbol arity. */
+  graph_SortNodes(graph, ana_NodeGreater);
+
+  /* A list of pairs (add, multiply) of distributive symbols */
+  distrPairs = list_Nil();
+
+  /* Now add undirected edges: there's an undirected edge between  */
+  /* two nodes if the symbols occur as top symbols in a positive   */
+  /* equation. */
+  for (scan = Clauses; !list_Empty(scan); scan = list_Cdr(scan)) {
+    CLAUSE c = list_Car(scan);
+    for (i = clause_FirstSuccedentLitIndex(c);
+	 i <= clause_LastSuccedentLitIndex(c); i++) {
+      if (clause_LiteralIsEquality(clause_GetLiteral(c, i))) {
+	/* Consider only positive equations */
+	TERM t1, t2;
+
+	if (fol_DistributiveEquation(clause_GetLiteralAtom(c,i), &Add, &Mult)) {
+	  /* Add a pair (Add, Mult) to <distrTerms> */
+	  distrPairs = list_Cons(list_PairCreate((POINTER)Add, (POINTER)Mult),
+				 distrPairs);
+	  /*fputs("\nDISTRIBUTIVITY: ", stdout);
+	    term_PrintPrefix(clause_GetLiteralAtom(c,i));
+	    fputs(" Add=", stdout); symbol_Print(Add);
+	    fputs(" Mult=", stdout); symbol_Print(Mult); fflush(stdout); DBG */
+	}
+
+	t1 = term_FirstArgument(clause_GetLiteralAtom(c, i));
+	t2 = term_SecondArgument(clause_GetLiteralAtom(c, i));
+
+	if  (!term_IsVariable(t1) && !term_IsVariable(t2) &&
+	     !term_EqualTopSymbols(t1, t2) &&  /* No self loops! */
+	     !term_HasSubterm(t1, t2) &&       /* No subterm property */
+	     !term_HasSubterm(t2, t1)) {
+	  n1 = graph_GetNode(graph, symbol_Index(term_TopSymbol(t1)));
+	  n2 = graph_GetNode(graph, symbol_Index(term_TopSymbol(t2)));
+	  /* Create an undirected edge by adding two directed edges */
+	  graph_AddEdge(n1, n2);
+	  graph_AddEdge(n2, n1);
+	  /* Use the node info for the degree of the node */
+	  ana_IncNodeDegree(n1);
+	  ana_IncNodeDegree(n2);
+	}
+      }
+    }
+  }
+  
+  /* putchar('\n');
+     for (scan = graph_Nodes(graph); !list_Empty(scan); scan = list_Cdr(scan)) {
+     n1 = list_Car(scan);
+     printf("(%s,%d,%u), ",
+     symbol_Name(symbol_GetSigSymbol(graph_NodeNumber(n1))),
+     graph_NodeNumber(n1), ana_NodeDegree(n1));
+     }
+     graph_Print(graph); fflush(stdout); DBG */
+
+  graph_DeleteDuplicateEdges(graph);
+  
+  /* Transform the undirected graph into a directed graph. */
+  for (scan = graph_Nodes(graph); !list_Empty(scan); scan = list_Cdr(scan)) {
+    n1 = list_Car(scan);
+    result = list_Nil(); /* Collect edges from n1 that shall be deleted */ 
+    for (scan2 = graph_NodeNeighbors(n1); !list_Empty(scan2);
+	 scan2 = list_Cdr(scan2)) {
+      int a1, a2;
+      n2 = list_Car(scan2);
+      /* Get the node degrees in the undirected graph with multiple edges */
+      i  = ana_NodeDegree(n1);
+      j  = ana_NodeDegree(n2);
+      a1 = symbol_Arity(symbol_GetSigSymbol(graph_NodeNumber(n1)));
+      a2 = symbol_Arity(symbol_GetSigSymbol(graph_NodeNumber(n2)));
+
+      if (i > j || (i==j && a1 >= a2)) {
+	/* symbol2 <= symbol1, so remove edge n1 -> n2 */
+	result = list_Cons(n2, result);
+      }
+      if (i < j || (i==j && a1 <= a2)) {
+	/* symbol1 <= symbol2, so remove edge n2 -> n1 */
+	graph_DeleteEdge(n2, n1);
+      }
+      /* NOTE: If (i==j && a1==a2) both edges are deleted! */
+    }
+    /* Now delete edges from n1 */
+    for ( ; !list_Empty(result); result = list_Pop(result))
+      graph_DeleteEdge(n1, list_Car(result));
+  }
+
+  if (!list_Empty(distrPairs) && !ana_BidirectionalDistributivity(distrPairs)) {
+    /* Enable RPO ordering, otherwise the default KBO will be used. */
+    flag_SetFlagValue(Flags, flag_ORD, flag_ORDRPOS);
+  }
+
+  /* Now examine the list of distribute symbols */
+  /* since they've highest priority.                  */
+  for ( ; !list_Empty(distrPairs); distrPairs = list_Pop(distrPairs)) {
+    scan = list_Car(distrPairs); /* A pair (Add, Mult) */
+    /* Addition */
+    n1 = graph_GetNode(graph,
+		       symbol_Index((SYMBOL)list_PairFirst(scan)));
+    /* Multiplication */
+    n2 = graph_GetNode(graph, 
+		       symbol_Index((SYMBOL)list_PairSecond(scan)));
+    /* Remove any edges between n1 and n2 */
+    graph_DeleteEdge(n1, n2);
+    graph_DeleteEdge(n2, n1);
+    /* Add one edge Addition -> Multiplication */
+    graph_AddEdge(n1, n2);
+    list_PairFree(scan);
+  }
+
+  /* fputs("\n------------------------",stdout);
+     graph_Print(graph); fflush(stdout); DBG */
+
+  /* Calculate the strongly connected components of the graph. */
+  /* <i> is the number of SCCs. */
+  i = graph_StronglyConnectedComponents(graph);
+
+  /* Now create the precedence list by scanning the nodes.        */
+  /* If there's a link between two strongly connected components  */
+  /* c1 and c2 then component_num(c1) > component_num(c2), so the */
+  /* following code creates a valid precedence list in descending */
+  /* order.                                                       */
+  result = list_Nil();
+  while (i-- > 0) {   /* for i = numberOfSCCs -1 dowto 0 */
+    for (scan = graph_Nodes(graph); !list_Empty(scan); scan = list_Cdr(scan)) {
+      n1 = list_Car(scan);
+      if (graph_NodeCompNum(n1) == i) {
+	/* The symbol represented by the node <n> belongs to component <i> */
+	s = symbol_GetSigSymbol(graph_NodeNumber(n1));
+	result = list_Cons((POINTER)s, result);
+      }
+    }
+  }
+
+  /* putchar('\n');
+     for (scan = result; !list_Empty(scan); scan = list_Cdr(scan)) {
+     s = (SYMBOL) list_Car(scan);
+     symbol_Print(s);
+     fputs(" > ", stdout);
+     }
+     putchar('\n'); fflush(stdout); DBG */
+
+  graph_Delete(graph);
+
+  return result;
+}
diff --git a/test/spass/analyze.h b/test/spass/analyze.h
new file mode 100644
index 0000000000000000000000000000000000000000..a44c893f655a167ee2285038127a507d5bc2b8fe
--- /dev/null
+++ b/test/spass/analyze.h
@@ -0,0 +1,121 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                ANALYSIS OF CLAUSE SETS                 * */
+/* *                                                        * */
+/* *  $Module:   ANALYZE                                    * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+ 
+#ifndef _ANALYZE_
+#define _ANALYZE_
+
+#include "search.h"
+#include "clause.h"
+#include "sort.h"
+#include "list.h"
+#include "graph.h"
+
+/**************************************************************/
+/* Global Variables                                           */
+/**************************************************************/
+
+extern BOOL ana_EQUATIONS;
+extern BOOL ana_SORTRES;
+extern BOOL ana_USORTRES;
+extern BOOL ana_SORTDECEQUATIONS;
+
+extern LIST ana_FINITEMONADICPREDICATES;
+
+/**************************************************************/
+/* Inline Functions                                           */
+/**************************************************************/
+
+static __inline__ BOOL ana_Equations(void)
+{
+  return ana_EQUATIONS;
+}
+
+static __inline__ BOOL ana_SortRestrictions(void)
+{
+  return ana_SORTRES;
+}
+
+static __inline__ BOOL ana_UnsolvedSortRestrictions(void)
+{
+  return ana_USORTRES;
+}
+
+static __inline__ BOOL ana_SortDecreasing(void)
+{
+  return ana_SORTDECEQUATIONS;
+}
+
+static __inline__ void ana_Init(void)
+{
+  ana_FINITEMONADICPREDICATES = list_Nil();
+}
+
+static __inline__ void ana_Free(void)
+{
+  list_Delete(ana_FINITEMONADICPREDICATES);
+}
+
+static __inline__ LIST ana_FinMonPredList(void)
+{
+  return ana_FINITEMONADICPREDICATES;
+}
+
+
+
+
+
+/**************************************************************/
+/* Inline Functions                                           */
+/**************************************************************/
+
+void ana_AnalyzeProblem(PROOFSEARCH, LIST);
+void ana_AnalyzeSortStructure(LIST, FLAGSTORE, PRECEDENCE);
+void ana_AutoConfiguration(LIST, FLAGSTORE, PRECEDENCE);
+void ana_ExploitSortAnalysis(FLAGSTORE);
+void ana_Print(FLAGSTORE, PRECEDENCE);
+
+#endif
diff --git a/test/spass/approx.h b/test/spass/approx.h
new file mode 100644
index 0000000000000000000000000000000000000000..5e50d39e0ba5b2f3e8dead1573c21d6c4ec27d55
--- /dev/null
+++ b/test/spass/approx.h
@@ -0,0 +1,61 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                  CLAUSE APPROXIMATION                  * */
+/* *                                                        * */
+/* *  $Module:   APPROX                                     * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1998, 1999, 2000, 2001                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* $RCSfile$ */
+
+#ifndef _APPROX_
+#define _APPROX_
+
+#include "list.h"
+#include "clause.h"
+
+void approx_Init(void);
+
+LIST approx_MonadicByProjection(LIST, FLAGSTORE, PRECEDENCE);
+LIST approx_MonadicByTermEncoding(LIST, FLAGSTORE, PRECEDENCE);
+LIST approx_MonadicMakeLinear(LIST, FLAGSTORE, PRECEDENCE);
+LIST approx_HornMonadicFlattenHeads(CLAUSE, BOOL, BOOL, FLAGSTORE, PRECEDENCE);
+LIST approx_MakeHorn(CLAUSE, FLAGSTORE, PRECEDENCE);
+
+#endif
diff --git a/test/spass/clause.c b/test/spass/clause.c
new file mode 100644
index 0000000000000000000000000000000000000000..6b2e3f6f53228c29226fb957d2e8589faa64e6d6
--- /dev/null
+++ b/test/spass/clause.c
@@ -0,0 +1,5008 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                   CLAUSES                              * */
+/* *                                                        * */
+/* *  $Module:   CLAUSE                                     * */
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                       * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "clause.h"
+
+/**************************************************************/
+/* Global variables and constants                             */
+/**************************************************************/
+
+/* Means weight of literal or clause is undefined */
+const NAT clause_WEIGHTUNDEFINED = NAT_MAX;
+
+int  clause_CLAUSECOUNTER;
+NAT  clause_STAMPID;
+
+/* The following array is used for bucket sort on clauses */
+#define clause_MAXWEIGHT 20
+LIST clause_SORT[clause_MAXWEIGHT+1];
+
+/**************************************************************/
+/* Inline functions                                           */
+/**************************************************************/
+
+static __inline__ void clause_FreeLitArray(CLAUSE Clause)
+{
+  NAT Length = clause_Length(Clause);
+  if (Length > 0)
+    memory_Free(Clause->literals, sizeof(LITERAL) * Length);
+}
+
+
+/**************************************************************/
+/* Primitive literal functions                                */
+/**************************************************************/
+
+BOOL clause_LiteralIsLiteral(LITERAL Literal)
+/*********************************************************
+  INPUT:   A literal.
+  RETURNS: TRUE, if 'Literal' is not NULL and has a predicate
+           symbol as its atoms top symbol.
+**********************************************************/
+{
+  return ((Literal != NULL) &&
+	  symbol_IsPredicate(clause_LiteralPredicate(Literal)));
+}
+
+NAT clause_LiteralComputeWeight(LITERAL Literal, FLAGSTORE Flags)
+/*********************************************************
+  INPUT:   A literal and a flag store.
+  RETURNS: The weight of the literal.
+  CAUTION: This function does not update the weight of the literal!
+**********************************************************/
+{
+  TERM Term;
+  int  Bottom;
+  NAT  Number;
+
+#ifdef CHECK
+  if (!clause_LiteralIsLiteral(Literal)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_LiteralComputeWeight :");
+    misc_ErrorReport("Illegal Input. Input not a literal.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Term = clause_LiteralSignedAtom(Literal);
+  Bottom = stack_Bottom();
+  Number = 0;
+  
+  do {
+    if (term_IsComplex(Term)) {
+      Number += flag_GetFlagValue(Flags, flag_FUNCWEIGHT);
+      stack_Push(term_ArgumentList(Term));
+    }
+    else
+      if (term_IsVariable(Term))
+	Number += flag_GetFlagValue(Flags, flag_VARWEIGHT);
+      else
+	Number += flag_GetFlagValue(Flags, flag_FUNCWEIGHT);
+    
+    while (!stack_Empty(Bottom) && list_Empty(stack_Top()))
+      stack_Pop();
+    if (!stack_Empty(Bottom)) {
+      Term = (TERM) list_Car(stack_Top());
+      stack_RplacTop(list_Cdr(stack_Top()));
+    }
+  } while (!stack_Empty(Bottom));
+
+  return Number;
+
+}
+
+LITERAL clause_LiteralCreate(TERM Atom, CLAUSE Clause)
+/**********************************************************
+  INPUT:   A Pointer to a signed Predicate-Term and one to a
+           clause it shall belong to.
+  RETURNS: An appropriate literal where the other values
+           are set to default values.
+  MEMORY:  A LITERAL_NODE is allocated.
+  CAUTION: The weight of the literal is not set correctly!
+***********************************************************/
+{
+  LITERAL Result;
+
+#ifdef CHECK
+  if (!term_IsTerm(Atom)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_LiteralCreate:");
+    misc_ErrorReport("\n Illegal input. Input not a term.");
+    misc_FinishErrorReport();
+  }
+  if (!symbol_IsPredicate(term_TopSymbol(Atom)) &&
+      (term_TopSymbol(Atom) != fol_Not())) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_LiteralCreate:");
+    misc_ErrorReport("\n Illegal input. No predicate- or negated term.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Result                = (LITERAL)memory_Malloc(sizeof(LITERAL_NODE));
+  
+  Result->atomWithSign  = Atom;
+  Result->oriented      = FALSE;
+  Result->weight        = clause_WEIGHTUNDEFINED;
+  Result->maxLit        = 0;
+  Result->owningClause  = Clause;
+
+  return Result;
+}
+
+
+LITERAL clause_LiteralCreateNegative(TERM Atom, CLAUSE Clause)
+/**********************************************************
+  INPUT:   A Pointer to a unsigned Predicate-Term and one to a
+           clause it shall belong to.
+  RETURNS: An appropriate literal where the other values
+           are set to default values and the term gets a sign.
+  MEMORY:  A LITERAL_NODE is allocated.
+  CAUTION: The weight of the literal is not set correctly!
+***********************************************************/
+{
+  LITERAL Result;
+
+#ifdef CHECK
+  if (!term_IsTerm(Atom)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_LiteralCreateNegative:");
+    misc_ErrorReport("\n Illegal input. Input not an atom.");
+    misc_FinishErrorReport();
+  }
+  if (!symbol_IsPredicate(term_TopSymbol(Atom)) &&
+      (term_TopSymbol(Atom) != fol_Not())) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_LiteralCreateNegative:");
+    misc_ErrorReport("\n Illegal input. Input term not normalized.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Result                = (LITERAL)memory_Malloc(sizeof(LITERAL_NODE));
+  
+  term_RplacSupertermList(Atom, list_Nil());
+
+  Result->atomWithSign  = term_Create(fol_Not(), list_List(Atom));
+  Result->oriented      = FALSE;
+  Result->maxLit        = 0;
+  Result->weight        = clause_WEIGHTUNDEFINED;
+  Result->owningClause  = Clause;
+
+  return Result;
+}
+
+
+void clause_LiteralDelete(LITERAL Literal)
+/*********************************************************
+  INPUT:   A literal, which has an unshared Atom. For Shared
+           literals clause_LiteralDeleteFromSharing(Lit) is
+	   available.
+  RETURNS: Nothing.
+  MEMORY:  The Atom of 'Literal' is deleted and its memory
+           is freed as well as the LITERAL_NODE.
+**********************************************************/
+{
+#ifdef CHECK
+  if (!clause_LiteralIsLiteral(Literal)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_LiteralDelete:");
+    misc_ErrorReport("\n Illegal input. Input not a literal.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  term_Delete(clause_LiteralSignedAtom(Literal));
+
+  clause_LiteralFree(Literal);
+}
+
+
+void clause_LiteralInsertIntoSharing(LITERAL Lit, SHARED_INDEX ShIndex)
+/**********************************************************
+  INPUT:   A Literal with an unshared Atom and an Index.
+  RETURNS: The literal with a shared Atom inserted into the
+           'Index'.
+  MEMORY:  Allocates TERM_NODE memory needed to insert 'Lit'
+           into the sharing and frees the memory of the
+           unshared Atom.
+***********************************************************/
+{
+
+  TERM Atom;
+  
+#ifdef CHECK
+  if (!clause_LiteralIsLiteral(Lit)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_LiteralInsertIntoSharing:");
+    misc_ErrorReport("\n Illegal literal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  Atom = clause_LiteralAtom(Lit);
+  
+  clause_LiteralSetAtom(Lit, sharing_Insert(Lit, Atom, ShIndex));
+  
+  term_Delete(Atom);
+}
+
+
+void clause_LiteralDeleteFromSharing(LITERAL Lit, SHARED_INDEX ShIndex)
+/**********************************************************
+  INPUT:   A Literal and an 'Index'.
+  RETURNS: Nothing.
+  MEMORY:  Deletes 'Lit' from Sharing, frees no more used
+           TERM memory and frees the LITERAL_NODE.
+********************************************************/
+{
+
+  TERM Atom;
+
+#ifdef CHECK
+  if (!clause_LiteralIsLiteral(Lit)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_LiteralDeleteFromSharing:");
+    misc_ErrorReport("\n Illegal literal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Atom = clause_LiteralAtom(Lit);
+
+  if (clause_LiteralIsNegative(Lit)) {
+    list_Free(term_ArgumentList(clause_LiteralSignedAtom(Lit)));
+    term_Free(clause_LiteralSignedAtom(Lit));
+  }
+ 
+  sharing_Delete(Lit, Atom, ShIndex);
+
+  clause_LiteralFree(Lit);
+
+}
+
+
+static LIST clause_CopyLitInterval(CLAUSE Clause, int Start, int End)
+/**************************************************************
+ INPUT:   A clause and two integers representing
+          literal indices.
+ RETURNS: Copies of all literals in <Clause> with index i and
+          in the interval [Start:End] are prepended to <List>.
+ MEMORY:  All atoms are copied.
+***************************************************************/
+{
+  TERM Atom;
+  LIST List;
+
+  List = list_Nil();
+
+  for ( ; Start <= End; Start++) {
+    Atom = term_Copy(clause_GetLiteralAtom(Clause, Start));
+    List = list_Cons(Atom, List);
+  }
+  
+  return List;
+}
+
+
+static LIST clause_CopyLitIntervalExcept(CLAUSE Clause, int Start, int End,
+					 int i)
+/**************************************************************
+ INPUT:   A clause and three integers representing
+          literal indeces.
+ RETURNS: A list of atoms from literals within the interval
+          [Start:End] except the literal at index <i>.
+ MEMORY:  All atoms are copied.
+***************************************************************/
+{
+  TERM Atom;
+  LIST Result;
+  
+  Result = list_Nil();
+  for ( ; End >= Start; End--)
+    if (End != i) {
+      Atom   = term_Copy(clause_GetLiteralAtom(Clause, End));
+      Result = list_Cons(Atom, Result);
+    }
+  return Result;
+}
+
+
+LIST clause_CopyConstraint(CLAUSE Clause)
+/**************************************************************
+ INPUT:   A clause.
+ RETURNS: The list of copied constraint literals from <Clause>.
+***************************************************************/
+{
+  return clause_CopyLitInterval(Clause,
+				clause_FirstConstraintLitIndex(Clause),
+				clause_LastConstraintLitIndex(Clause));
+}
+
+
+LIST clause_CopyAntecedentExcept(CLAUSE Clause, int i)
+/**************************************************************
+ INPUT:   A clause.
+ RETURNS: A list containing copies of all antecedent literals
+          except <i>.
+***************************************************************/
+{
+  return clause_CopyLitIntervalExcept(Clause,
+				      clause_FirstAntecedentLitIndex(Clause),
+				      clause_LastAntecedentLitIndex(Clause),
+				      i);
+}
+
+LIST clause_CopySuccedent(CLAUSE Clause)
+/**************************************************************
+ INPUT:   A clause.
+ RETURNS: The list of copied succedent literals from <Clause>.
+***************************************************************/
+{
+  return clause_CopyLitInterval(Clause,
+				clause_FirstSuccedentLitIndex(Clause),
+				clause_LastSuccedentLitIndex(Clause));
+}
+
+
+LIST clause_CopySuccedentExcept(CLAUSE Clause, int i)
+/**************************************************************
+ INPUT:   A clause.
+ RETURNS: A list containing copies of all succedent literals
+          except <i>.
+***************************************************************/
+{
+  return clause_CopyLitIntervalExcept(Clause,
+				      clause_FirstSuccedentLitIndex(Clause),
+				      clause_LastSuccedentLitIndex(Clause),
+				      i);
+}
+
+
+/**************************************************************/
+/* Specials                                                   */
+/**************************************************************/
+
+BOOL clause_IsUnorderedClause(CLAUSE Clause)
+/*********************************************************
+  INPUT:   A clause.
+  RETURNS: TRUE, if the invariants concerning splitting etc. hold
+           Invariants concerning maximality restrictions are not tested.
+**********************************************************/
+{
+  return ((Clause != NULL) &&
+	  clause_CheckSplitLevel(Clause) &&
+	  (clause_IsEmptyClause(Clause) ||
+	   /* Check the first literal as a "random" sample */
+	   clause_LiteralIsLiteral(clause_GetLiteral(Clause,clause_FirstLitIndex()))) &&
+	  (clause_SplitLevel(Clause) == 0 || Clause->splitfield_length>0) &&
+	  clause_DependsOnSplitLevel(Clause,clause_SplitLevel(Clause)));
+}
+
+
+BOOL clause_IsClause(CLAUSE Clause, FLAGSTORE FlagStore, PRECEDENCE Precedence)
+/*********************************************************
+  INPUT:   A clause, a flag store and a precedence.
+  RETURNS: TRUE, if literals are correctly ordered and the
+           invariants concerning splitting etc. hold
+**********************************************************/
+{
+  int     i;
+  LITERAL ActLit;
+
+  if (!clause_IsUnorderedClause(Clause))
+    return FALSE;
+
+  for (i=clause_FirstAntecedentLitIndex(Clause);i<=clause_LastSuccedentLitIndex(Clause);i++) {
+    ActLit = clause_GetLiteral(Clause,i);
+    if (fol_IsEquality(clause_LiteralSignedAtom(ActLit))) {
+      ord_RESULT HelpRes;
+	
+      HelpRes =
+	ord_Compare(term_FirstArgument(clause_LiteralSignedAtom(ActLit)),
+		    term_SecondArgument(clause_LiteralSignedAtom(ActLit)),
+		    FlagStore, Precedence);
+	
+      if (ord_IsSmallerThan(HelpRes))
+	return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+
+BOOL clause_ContainsPositiveEquations(CLAUSE Clause)
+/*********************************************************
+  INPUT:   A clause.
+  RETURNS: TRUE, if the clause contains a positive equality literal.
+**********************************************************/
+{
+  int i;
+  
+  for (i = clause_FirstSuccedentLitIndex(Clause);
+       i < clause_Length(Clause);
+       i++)
+    if (clause_LiteralIsEquality(clause_GetLiteral(Clause, i)))
+      return TRUE;
+
+  return FALSE;
+}
+
+
+BOOL clause_ContainsNegativeEquations(CLAUSE Clause)
+/*********************************************************
+  INPUT:   A clause.
+  RETURNS: TRUE, if the clause contains a positive equality literal.
+**********************************************************/
+{
+  int i;
+  
+  for (i = clause_FirstAntecedentLitIndex(Clause);
+       i < clause_FirstSuccedentLitIndex(Clause);
+       i++)
+    if (clause_LiteralIsEquality(clause_GetLiteral(Clause, i)))
+      return TRUE;
+
+  return FALSE;
+}
+
+
+int clause_ContainsFolAtom(CLAUSE Clause, BOOL *Prop, BOOL *Grd, BOOL *Monadic,
+			   BOOL *NonMonadic)
+/*********************************************************
+  INPUT:   A clause.
+  RETURNS: The number of boolean variables changed.
+           If <*Prop> is FALSE and the clause contains a propositional
+	   variable, it is changed to TRUE.
+	   If <*Grd> is FALSE and the clause contains a non-propositional
+	   ground atom, it is changed to TRUE.
+           If <*Monadic> is FALSE and the clause contains a monadic atom,
+	      it is changed to TRUE.
+	   If <*NonMonadic> is FALSE and the clause contains an at least
+	   2-place non-equality atom, it is changed to TRUE.
+**********************************************************/
+{
+  int  i,Result,Arity;
+  BOOL Ground;
+
+  Result = 0;
+  i      = clause_FirstLitIndex();
+
+  while (Result < 4 &&
+	 i < clause_Length(Clause) &&
+	 (!(*Prop) || !(*Monadic) || !(*NonMonadic))) {
+    Arity  = symbol_Arity(term_TopSymbol(clause_GetLiteralAtom(Clause,i)));
+    Ground = term_IsGround(clause_GetLiteralAtom(Clause,i));
+    if (!(*Prop) && Arity == 0) {
+      Result++;
+      *Prop = TRUE;
+    }
+    if (!(*Grd) && Arity > 0 && Ground &&
+	!fol_IsEquality(clause_GetLiteralAtom(Clause,i))) {
+      Result++;
+      *Grd = TRUE;
+    }
+    if (!(*Monadic) && Arity == 1 && !Ground) {
+      Result++;
+      *Monadic = TRUE;
+    }
+    if (!(*NonMonadic) && Arity > 1 && !Ground &&
+	!fol_IsEquality(clause_GetLiteralAtom(Clause,i))) {
+      Result++;
+      *NonMonadic = TRUE;
+    }
+    i++;
+  }
+  return Result;
+}
+
+
+BOOL clause_ContainsVariables(CLAUSE Clause)
+/*********************************************************
+  INPUT:   A clause.
+  RETURNS: TRUE, if the clause contains at least one variable
+**********************************************************/
+{
+  int  i;
+  TERM Term;
+
+  for (i = clause_FirstLitIndex(); i < clause_Length(Clause); i++) {
+    Term = clause_GetLiteralAtom(Clause,i);
+    if (term_NumberOfVarOccs(Term)>0)
+      return TRUE;
+  }
+
+  return FALSE;
+}
+
+
+void clause_ContainsSortRestriction(CLAUSE Clause, BOOL *Sortres, BOOL *USortres)
+/*********************************************************
+  INPUT:   A clause.
+  RETURNS: TRUE, if the clause contains a negative monadic atom with
+           a variable argument
+**********************************************************/
+{
+  int  i;
+  TERM Term;
+
+  for (i = clause_FirstLitIndex();
+       i <= clause_LastAntecedentLitIndex(Clause) && (!*Sortres || !*USortres);
+       i++) {
+    Term = clause_GetLiteralAtom(Clause,i);
+    if (symbol_IsBaseSort(term_TopSymbol(Term))) {
+      *USortres = TRUE;
+      if (symbol_IsVariable(term_TopSymbol(term_FirstArgument(Term))))
+	*Sortres = TRUE;
+    }
+  }
+}
+
+BOOL clause_ContainsFunctions(CLAUSE Clause)
+/*********************************************************
+  INPUT:   A clause.
+  RETURNS: TRUE, if the clause contains at least one function symbol
+**********************************************************/
+{
+  int  i;
+  TERM Term;
+
+  for (i = clause_FirstLitIndex(); i < clause_Length(Clause); i++) {
+    Term = clause_GetLiteralAtom(Clause,i);
+    if (term_ContainsFunctions(Term))
+      return TRUE;
+  }
+
+  return FALSE;
+}
+
+BOOL clause_ContainsSymbol(CLAUSE Clause, SYMBOL Symbol)
+/*********************************************************
+  INPUT:   A clause and a symbol.
+  RETURNS: TRUE, if the clause contains the symbol
+**********************************************************/
+{
+  int  i;
+
+  for (i = clause_FirstLitIndex(); i < clause_Length(Clause); i++)
+    if (term_ContainsSymbol(clause_GetLiteralAtom(Clause,i), Symbol))
+      return TRUE;
+  return FALSE;
+}
+
+NAT clause_NumberOfSymbolOccurrences(CLAUSE Clause, SYMBOL Symbol)
+/*********************************************************
+  INPUT:   A clause and a symbol.
+  RETURNS: the number of occurrences of <Symbol> in <Clause>
+**********************************************************/
+{
+  int  i;
+  NAT  Result;
+
+  Result = 0;
+
+  for (i = clause_FirstLitIndex(); i < clause_Length(Clause); i++)
+    Result += term_NumberOfSymbolOccurrences(clause_GetLiteralAtom(Clause,i), Symbol);
+
+  return Result;
+}
+
+BOOL clause_ImpliesFiniteDomain(CLAUSE Clause)
+/*********************************************************
+  INPUT:   A clause.
+  RETURNS: TRUE, if the clause consists of a positive disjunction
+           of equations, where each equation is of the form "x=t" for
+	   some variable "x" and ground term "t"
+**********************************************************/
+{
+  int  i;
+  TERM Term;
+
+  if (clause_FirstLitIndex() != clause_FirstSuccedentLitIndex(Clause))
+    return FALSE;
+
+  for (i = clause_FirstLitIndex(); i < clause_Length(Clause); i++) {
+    Term = clause_GetLiteralTerm(Clause,i);
+    if (!symbol_Equal(term_TopSymbol(Term),fol_Equality()) ||
+	(!symbol_IsVariable(term_TopSymbol(term_FirstArgument(Term))) &&
+	 !symbol_IsVariable(term_TopSymbol(term_SecondArgument(Term)))) ||
+	(symbol_IsVariable(term_TopSymbol(term_FirstArgument(Term))) &&
+	 !term_IsGround(term_SecondArgument(Term))) ||
+	(symbol_IsVariable(term_TopSymbol(term_SecondArgument(Term))) &&
+	 !term_IsGround(term_FirstArgument(Term))))
+      return FALSE;
+  }
+
+  return TRUE;
+}
+
+BOOL clause_ImpliesNonTrivialDomain(CLAUSE Clause)
+/*********************************************************
+  INPUT:   A clause.
+  RETURNS: TRUE, if the clause consists of a negative equation
+           with two syntactically different arguments
+**********************************************************/
+{
+  if (clause_Length(Clause) == 1 &&
+      !clause_HasEmptyAntecedent(Clause) &&
+      clause_LiteralIsEquality(clause_FirstAntecedentLit(Clause)) &&
+      !term_Equal(term_FirstArgument(clause_LiteralAtom(clause_FirstAntecedentLit(Clause))),
+		  term_SecondArgument(clause_LiteralAtom(clause_FirstAntecedentLit(Clause)))))
+    return TRUE;
+  
+  return FALSE;
+}
+
+LIST clause_FiniteMonadicPredicates(LIST Clauses)
+/*********************************************************
+  INPUT:   A list of clauses.
+  RETURNS: A list of all predicate symbols that are guaranteed
+           to have a finite extension in any minimal Herbrand model.
+	   These predicates must only positively occur
+           in unit clauses and must have a ground term argument.
+**********************************************************/
+{
+  LIST   Result, NonFinite, Scan;
+  CLAUSE Clause;
+  int    i, n;
+  SYMBOL Pred;
+
+  Result    = list_Nil();
+  NonFinite = list_Nil();
+
+  for (Scan=Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Clause = (CLAUSE)list_Car(Scan);
+    n      = clause_Length(Clause);
+    for (i=clause_FirstSuccedentLitIndex(Clause);i<n;i++) {
+      Pred = term_TopSymbol(clause_GetLiteralAtom(Clause,i));
+      if (symbol_Arity(Pred) == 1 &&
+	  !list_PointerMember(NonFinite, (POINTER)Pred)) {
+	if (term_NumberOfVarOccs(clause_GetLiteralAtom(Clause,i)) > 0 ||
+	    n > 1) {
+	  NonFinite = list_Cons((POINTER)Pred, NonFinite);
+	  Result    = list_PointerDeleteElement(Result, (POINTER)Pred);
+	}
+	else {
+	  if (!list_PointerMember(Result, (POINTER)Pred))
+	    Result = list_Cons((POINTER)Pred, Result);
+	}
+      }
+    }
+  }
+  list_Delete(NonFinite);
+
+  Result = list_PointerDeleteElement(Result, (POINTER)fol_Equality());
+
+  return Result;
+}
+
+NAT clause_NumberOfVarOccs(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A Clause.
+  RETURNS: The number of variable occurrences in the clause.
+***************************************************************/
+{
+  int i,n;
+  NAT Result;
+
+  Result = 0;
+  n      = clause_Length(Clause);
+
+  for (i = clause_FirstLitIndex(); i < n; i++)
+    Result += term_NumberOfVarOccs(clause_GetLiteralTerm(Clause,i));
+  
+  return Result;
+}
+
+
+NAT clause_ComputeWeight(CLAUSE Clause, FLAGSTORE Flags)
+/**************************************************************
+  INPUT:   A clause and a flag store.
+  RETURNS: The Weight of the literals in the clause,
+           up to now the number of variable symbols plus
+	   twice the number of signature symbols.
+  EFFECT:  The weight of the literals is updated, but not the
+           weight of the clause!
+***************************************************************/
+{
+  int     i, n;
+  NAT     Weight;
+  LITERAL Lit;
+
+  Weight = 0;
+  n      = clause_Length(Clause);
+
+  for (i = clause_FirstLitIndex(); i < n; i++) {
+    Lit = clause_GetLiteral(Clause, i);
+    clause_UpdateLiteralWeight(Lit, Flags);
+    Weight += clause_LiteralWeight(Lit);
+  }
+  return Weight;
+}
+
+
+NAT clause_ComputeTermDepth(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A Clause.
+  RETURNS: Maximal depth of a literal in <Clause>.
+***************************************************************/
+{
+  int     i,n;
+  NAT     Depth,Help;
+
+#ifdef CHECK
+  if (!clause_IsUnorderedClause(Clause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_ComputeTermDepth:");
+    misc_ErrorReport("\n Illegal input. Input not a clause.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Depth = 0;
+  n     = clause_Length(Clause);
+
+  for (i = clause_FirstLitIndex();i < n;i++) {
+    Help   = term_Depth(clause_GetLiteralAtom(Clause,i));
+    if (Help > Depth)
+      Depth = Help;
+  }
+  return Depth;
+}
+
+NAT clause_MaxTermDepthClauseList(LIST Clauses)
+/**************************************************************
+  INPUT:   A list of clauses.
+  RETURNS: Maximal depth of a clause in <Clauses>.
+***************************************************************/
+{
+  NAT  Depth,Help;
+
+  Depth = 0;
+
+  while (!list_Empty(Clauses)) {
+    Help = clause_ComputeTermDepth(list_Car(Clauses));
+    if (Help > Depth)
+      Depth = Help;
+    Clauses = list_Cdr(Clauses);
+  }
+
+  return Depth;
+}
+
+
+NAT clause_ComputeSize(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A Clause.
+  RETURNS: The Size of the literals in the clause,
+           up to now the number of symbols.
+***************************************************************/
+{
+  int     i,n;
+  NAT     Size;
+
+#ifdef CHECK
+  if (!clause_IsUnorderedClause(Clause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_ComputeSize:");
+    misc_ErrorReport("\n Illegal input. Input not a clause.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Size = 0;
+  n    = clause_Length(Clause);
+
+  for (i = clause_FirstLitIndex();i < n;i++)
+    Size += term_ComputeSize(clause_GetLiteralTerm(Clause,i));
+  
+  return Size;
+}
+
+
+BOOL clause_WeightCorrect(CLAUSE Clause, FLAGSTORE Flags, PRECEDENCE Precedence)
+/*********************************************************
+  INPUT:   A clause, a flag store and a precedence.
+  RETURNS: TRUE iff the weight fields of the clause and its
+           literals are correct.
+**********************************************************/
+{
+  int     i, n;
+  NAT     Weight, Help;
+  LITERAL Lit;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_WeightCorrect:");
+    misc_ErrorReport("\n Illegal input. Input not a clause.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Weight = 0;
+  n      = clause_Length(Clause);
+
+  for (i = clause_FirstLitIndex(); i < n; i++) {
+    Lit  = clause_GetLiteral(Clause, i);
+    Help = clause_LiteralComputeWeight(Lit, Flags);
+    if (Help != clause_LiteralWeight(Lit))
+      return FALSE;
+    Weight += Help;
+  }
+
+  return (clause_Weight(Clause) == Weight);
+}
+
+
+LIST clause_InsertWeighed(CLAUSE Clause, LIST UsList, FLAGSTORE Flags,
+			  PRECEDENCE Precedence)
+/*********************************************************
+  INPUT:   A clause, a list to insert the clause into,
+           a flag store and a precedence.
+  RETURNS: The list where the clause is inserted wrt its
+           weight (Weight(Car(list)) <= Weight(Car(Cdr(list)))).
+  MEMORY:  A new listnode is allocated.
+**********************************************************/
+{
+  LIST Scan;
+  NAT  Weight;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_InsertWeighted:");
+    misc_ErrorReport("\n Illegal input. Input not a clause.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Weight = clause_Weight(Clause);
+
+  Scan = UsList;
+
+  if (list_Empty(Scan) ||
+      (clause_Weight(list_Car(Scan)) > Weight)) {
+    return list_Cons(Clause, Scan);
+
+  } else {
+    while (!list_Empty(list_Cdr(Scan)) &&
+	   (clause_Weight(list_Car(list_Cdr(Scan))) <= Weight)) {
+      Scan = list_Cdr(Scan);
+    }
+    list_Rplacd(Scan, list_Cons(Clause, list_Cdr(Scan)));
+    return UsList;
+  }
+}
+
+
+LIST clause_ListSortWeighed(LIST Clauses)
+/*********************************************************
+  INPUT:   A list of clauses.
+  RETURNS: The clause list sorted with respect to the weight
+           of clauses, minimal weight first.
+  EFFECT:  The original list is destructively changed!
+           This function doesn't sort stable!
+           The function uses bucket sort for clauses with weight
+	   smaller than clause_MAXWEIGHT, and the usual list sort
+	   function for clauses with weight >= clause_MAXWEIGHT.
+	   This implies the function uses time O(n-c + c*log c),
+	   where n is the length of the list and c is the number
+	   of clauses with weight >= clause_MAXWEIGHT.
+	   For c=0 you get time O(n), for c=n you get time (n*log n).
+**********************************************************/
+{
+  int  weight;
+  LIST Scan;
+
+  for (Scan=Clauses; !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+    weight = clause_Weight(list_Car(Scan));
+    if (weight < clause_MAXWEIGHT)
+      clause_SORT[weight] = list_Cons(list_Car(Scan),clause_SORT[weight]);
+    else
+      clause_SORT[clause_MAXWEIGHT] = list_Cons(list_Car(Scan),clause_SORT[clause_MAXWEIGHT]);
+  }
+  Scan = list_NumberSort(clause_SORT[clause_MAXWEIGHT],
+			 (NAT (*)(POINTER)) clause_Weight);
+  clause_SORT[clause_MAXWEIGHT] = list_Nil();
+  for (weight = clause_MAXWEIGHT-1; weight >= 0; weight--) {
+    Scan                = list_Nconc(clause_SORT[weight],Scan);
+    clause_SORT[weight] = list_Nil();
+  }
+  list_Delete(Clauses);
+  return Scan;
+}
+
+
+LITERAL clause_LiteralCopy(LITERAL Literal)
+/*********************************************************
+  INPUT:   A literal.
+  RETURNS: An unshared copy of the literal, where the owning
+           clause-slot is set to NULL.
+  MEMORY:  Memory for a new LITERAL_NODE and all its TERMs
+           subterms is allocated.
+**********************************************************/
+{
+
+  LITERAL Result;
+
+#ifdef CHECK
+  if (!clause_LiteralIsLiteral(Literal)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_LiteralCopy:");
+    misc_ErrorReport("\n Illegal input. Input not a literal.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Result                = (LITERAL)memory_Malloc(sizeof(LITERAL_NODE));
+  
+  Result->atomWithSign  = term_Copy(clause_LiteralSignedAtom(Literal));
+  Result->oriented      = clause_LiteralIsOrientedEquality(Literal);
+
+  Result->maxLit        = Literal->maxLit;
+  Result->weight        = Literal->weight;
+  Result->owningClause  = (POINTER)NULL;
+
+  return Result;
+}
+
+
+CLAUSE clause_Copy(CLAUSE Clause)
+/*********************************************************
+  INPUT:   A Clause.
+  RETURNS: An unshared copy of the Clause.
+  MEMORY:  Memory for a new CLAUSE_NODE, LITERAL_NODE and
+           all its TERMs subterms is allocated.
+**********************************************************/
+{
+
+  CLAUSE Result;
+  int i,c,a,s,l;
+
+  Result                = (CLAUSE)memory_Malloc(sizeof(CLAUSE_NODE));
+
+  Result->clausenumber  = clause_Number(Clause);
+  Result->maxVar        = clause_MaxVar(Clause);
+  Result->flags         = Clause->flags;
+  clause_InitSplitData(Result);
+  Result->validlevel    = clause_SplitLevel(Clause);
+  clause_SetSplitField(Result, Clause->splitfield, Clause->splitfield_length);
+  Result->depth         = clause_Depth(Clause);
+  Result->weight        = Clause->weight;
+  Result->parentCls     = list_Copy(clause_ParentClauses(Clause));
+  Result->parentLits    = list_Copy(clause_ParentLiterals(Clause));
+  Result->origin        = clause_Origin(Clause);
+
+  Result->c             = (c = clause_NumOfConsLits(Clause));
+  Result->a             = (a = clause_NumOfAnteLits(Clause));
+  Result->s             = (s = clause_NumOfSuccLits(Clause));
+
+  l = c + a + s;
+  if (l != 0)
+    Result->literals      = (LITERAL *)memory_Malloc(l * sizeof(LITERAL));
+
+  for (i = 0; i < l; i++) {
+    clause_SetLiteral(Result, i,
+		      clause_LiteralCopy(clause_GetLiteral(Clause, i)));
+    clause_LiteralSetOwningClause((Result->literals[i]), Result);
+  }
+
+  return Result;
+}
+
+
+SYMBOL clause_LiteralMaxVar(LITERAL Literal)
+/*********************************************************
+  INPUT:   A literal.
+  RETURNS: The maximal symbol of the literals variables,
+           if the literal is ground, symbol_GetInitialStandardVarCounter().
+**********************************************************/
+{
+
+  TERM Term;
+  int Bottom;
+  SYMBOL MaxSym,Help;
+
+#ifdef CHECK
+  if (!clause_LiteralIsLiteral(Literal)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_LiteralMaxVar:");
+    misc_ErrorReport("\n Illegal input. Input not a literal.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Bottom = stack_Bottom();
+  MaxSym = symbol_GetInitialStandardVarCounter();
+  Term   = clause_LiteralAtom(Literal);
+
+  do {
+    if (term_IsComplex(Term))
+      stack_Push(term_ArgumentList(Term));
+    else
+      if (term_IsVariable(Term))
+	MaxSym = ((MaxSym < (Help = term_TopSymbol(Term))) ?
+		  Help : MaxSym);
+    while (!stack_Empty(Bottom) && list_Empty(stack_Top()))
+      stack_Pop();
+    if (!stack_Empty(Bottom)) {
+      Term = (TERM) list_Car(stack_Top());
+      stack_RplacTop(list_Cdr(stack_Top()));
+    }
+  } while (!stack_Empty(Bottom));
+
+  return MaxSym;
+}
+
+
+SYMBOL clause_AtomMaxVar(TERM Term)
+/*********************************************************
+  INPUT:   A term.
+  RETURNS: The maximal symbol of the lcontained variables,
+           if <Term> is ground, symbol_GetInitialStandardVarCounter().
+**********************************************************/
+{
+  int Bottom;
+  SYMBOL VarSym,Help;
+
+  Bottom = stack_Bottom();
+  VarSym = symbol_GetInitialStandardVarCounter();
+
+  do {
+    if (term_IsComplex(Term))
+      stack_Push(term_ArgumentList(Term));
+    else
+      if (term_IsVariable(Term))
+	VarSym = ((VarSym < (Help = term_TopSymbol(Term))) ?
+		  Help : VarSym);
+    while (!stack_Empty(Bottom) && list_Empty(stack_Top()))
+      stack_Pop();
+    if (!stack_Empty(Bottom)) {
+      Term = (TERM)list_Car(stack_Top());
+      stack_RplacTop(list_Cdr(stack_Top()));
+    }
+  } while (!stack_Empty(Bottom));
+
+  return VarSym;
+}
+
+
+void clause_SetMaxLitFlags(CLAUSE Clause, FLAGSTORE FlagStore,
+			   PRECEDENCE Precedence)
+/**********************************************************
+  INPUT:   A clause, a flag store and a precedence.
+  RETURNS: Nothing.
+  EFFECT:  Sets the maxLit-flag for maximal literals.
+***********************************************************/
+{
+  int        i,j,n,fa;
+  LITERAL    ActLit,CompareLit;
+  BOOL       Result, Twin;
+  ord_RESULT HelpRes;
+  
+  n   = clause_Length(Clause);
+  fa  = clause_FirstAntecedentLitIndex(Clause);
+  clause_RemoveFlag(Clause,CLAUSESELECT);
+  for (i = clause_FirstLitIndex(); i < n; i++)
+    clause_LiteralFlagReset(clause_GetLiteral(Clause, i));
+  if (term_StampOverflow(clause_STAMPID))
+    for (i = clause_FirstLitIndex(); i < n; i++)
+      term_ResetTermStamp(clause_LiteralSignedAtom(clause_GetLiteral(Clause, i)));
+  term_StartStamp();
+
+  /*printf("\n Start: "); clause_Print(Clause);*/
+
+  for (i = fa; i < n; i++) {
+    ActLit = clause_GetLiteral(Clause, i);
+    if (!term_HasTermStamp(clause_LiteralSignedAtom(ActLit))) {
+      Result  = TRUE;
+      Twin    = FALSE;
+      for (j = fa; j < n && Result; j++)
+	if (i != j) {
+	  CompareLit = clause_GetLiteral(Clause, j);
+	  HelpRes    = ord_LiteralCompare(clause_LiteralSignedAtom(ActLit),
+					  clause_LiteralIsOrientedEquality(ActLit),
+					  clause_LiteralSignedAtom(CompareLit),
+					  clause_LiteralIsOrientedEquality(CompareLit),
+					  FALSE, FlagStore, Precedence);
+	  
+	  /*printf("\n\tWe compare: ");
+	    fol_PrintDFG(clause_LiteralAtom(ActLit));
+	    putchar(' ');
+	    fol_PrintDFG(clause_LiteralAtom(CompareLit));
+	    printf(" Result: "); ord_Print(HelpRes);*/
+
+	  if (ord_IsEqual(HelpRes))
+	    Twin = TRUE;
+	  if (ord_IsSmallerThan(HelpRes))
+	    Result = FALSE;
+	  if (ord_IsGreaterThan(HelpRes))
+	    term_SetTermStamp(clause_LiteralSignedAtom(CompareLit));
+	}
+      if (Result) {
+	clause_LiteralSetFlag(ActLit, MAXIMAL);
+	if (!Twin)
+	  clause_LiteralSetFlag(ActLit, STRICTMAXIMAL);
+      }
+    }
+  }
+  term_StopStamp();
+  /*printf("\n End: "); clause_Print(Clause);*/
+}
+
+
+SYMBOL clause_SearchMaxVar(CLAUSE Clause)
+/**********************************************************
+  INPUT:   A clause.
+  RETURNS: The maximal symbol of the clauses variables.
+           If the clause is ground, symbol_GetInitialStandardVarCounter().
+***********************************************************/
+{
+  int i, n;
+  SYMBOL Help, MaxSym;
+  
+  n = clause_Length(Clause);
+
+  MaxSym = symbol_GetInitialStandardVarCounter();
+
+  for (i = 0; i < n; i++) {
+    Help = clause_LiteralMaxVar(clause_GetLiteral(Clause, i));
+    if (Help > MaxSym)
+      MaxSym = Help;
+  }
+  return MaxSym;
+}
+
+
+void clause_RenameVarsBiggerThan(CLAUSE Clause, SYMBOL MinVar)
+/**********************************************************
+  INPUT:   A clause and a variable symbol.
+  RETURNS: The clause with variables renamed in a way, that
+           all vars are (excl.) bigger than MinVar.
+***********************************************************/
+{
+  int i,n;
+  
+#ifdef CHECK
+  if (!clause_IsUnorderedClause(Clause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_RenameVarsBiggerThan:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (MinVar != symbol_GetInitialStandardVarCounter()) {
+    n = clause_Length(Clause);
+
+    term_StartMaxRenaming(MinVar);
+
+    for (i = clause_FirstLitIndex(); i < n; i++)
+      term_Rename(clause_GetLiteralTerm(Clause, i));
+  }
+}
+
+void clause_Normalize(CLAUSE Clause)
+/**********************************************************
+  INPUT:   A clause.
+  RETURNS: The term with normalized Variables, DESTRUCTIVE
+           on the variable subterms' topsymbols.
+***********************************************************/
+{
+  int i,n;
+  
+  n = clause_Length(Clause);
+
+  term_StartMinRenaming();
+
+  for (i = clause_FirstLitIndex(); i < n; i++)
+    term_Rename(clause_GetLiteralTerm(Clause, i));
+}
+
+
+void clause_SubstApply(SUBST Subst, CLAUSE Clause)
+/**********************************************************
+  INPUT:   A clause.
+  RETURNS: Nothing.
+  EFFECTS: Applies the substitution to the clause.
+***********************************************************/
+{
+  int i,n;
+
+#ifdef CHECK
+  if (!clause_IsUnorderedClause(Clause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_SubstApply:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  n = clause_Length(Clause);
+
+  for (i=clause_FirstLitIndex(); i<n; i++)
+    clause_LiteralSetAtom(clause_GetLiteral(Clause, i),
+			  subst_Apply(Subst,clause_GetLiteralAtom(Clause,i)));
+}
+
+
+void clause_ReplaceVariable(CLAUSE Clause, SYMBOL Var, TERM Term)
+/**********************************************************
+  INPUT:   A clause, a variable symbol, and a term.
+  RETURNS: Nothing.
+  EFFECTS: All occurences of the variable <Var> in <Clause>
+           are replaced by copies if <Term>.
+  CAUTION: The maximum variable of the clause is not updated!
+***********************************************************/
+{
+  int i, li;
+
+#ifdef CHECK
+  if (!symbol_IsVariable(Var)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_ReplaceVariable: symbol is not a variable");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  li = clause_LastLitIndex(Clause);
+  for (i = clause_FirstLitIndex(); i <= li; i++)
+    term_ReplaceVariable(clause_GetLiteralAtom(Clause,i), Var, Term);
+}
+
+
+void clause_UpdateMaxVar(CLAUSE Clause)
+/**********************************************************
+  INPUT:   A clause.
+  RETURNS: Nothing.
+  EFFECTS: Actualizes the MaxVar slot wrt the actual literals.
+***********************************************************/
+{
+  clause_SetMaxVar(Clause, clause_SearchMaxVar(Clause));
+}
+
+
+
+void clause_OrientEqualities(CLAUSE Clause, FLAGSTORE FlagStore, 
+			     PRECEDENCE Precedence)
+/**********************************************************
+  INPUT:   An unshared clause, a flag store and a precedence.
+  RETURNS: Nothing.
+  EFFECTS: Reorders the arguments of equality literals
+           wrt. the ordering. Thus first arguments aren't smaller
+	   after the application.
+***********************************************************/
+{
+  int        i,length;
+  LITERAL    EqLit;
+  ord_RESULT HelpRes;
+
+  /*printf("\n Clause: ");clause_Print(Clause);*/
+
+  length = clause_Length(Clause);
+
+  for (i = clause_FirstLitIndex(); i < length; i++) {
+    EqLit = clause_GetLiteral(Clause, i);
+
+    if (clause_LiteralIsEquality(EqLit)) {
+      HelpRes = ord_Compare(term_FirstArgument(clause_LiteralAtom(EqLit)),
+			    term_SecondArgument(clause_LiteralAtom(EqLit)),
+			    FlagStore, Precedence);
+      
+      /*printf("\n\tWe compare: ");
+      fol_PrintDFG(term_FirstArgument(clause_LiteralAtom(EqLit)));
+      putchar(' ');
+      fol_PrintDFG(term_SecondArgument(clause_LiteralAtom(EqLit)));
+      printf("\nResult: "); ord_Print(HelpRes);*/
+
+      switch(HelpRes) {
+
+      case ord_SMALLER_THAN:
+	/* printf("\nSwapping: ");
+	   term_Print(clause_LiteralAtom(EqLit)); DBG */
+	term_EqualitySwap(clause_LiteralAtom(EqLit));
+	clause_LiteralSetOrientedEquality(EqLit);
+	/*	Swapped = TRUE; */
+	break;
+      case ord_GREATER_THAN:
+	clause_LiteralSetOrientedEquality(EqLit);
+	break;
+      default:
+	clause_LiteralSetNoOrientedEquality(EqLit);
+	break;
+      }
+    }
+    else
+      clause_LiteralSetNoOrientedEquality(EqLit);
+  }
+}
+
+
+void  clause_InsertFlatIntoIndex(CLAUSE Clause, st_INDEX Index)
+/**********************************************************
+  INPUT:   An unshared clause and an index.
+  EFFECT:  The atoms of <Clause> are inserted into the index.
+           A link from the atom to its literal via the supertermlist
+	   is established.
+***********************************************************/
+{
+  int     i,n;
+  LITERAL Lit;
+  TERM    Atom    ;
+
+  n = clause_Length(Clause);
+
+  for (i=clause_FirstLitIndex();i<n;i++) {
+    Lit  = clause_GetLiteral(Clause,i);
+    Atom = clause_LiteralAtom(Lit);
+    term_RplacSupertermList(Atom, list_List(Lit));
+    st_EntryCreate(Index, Atom, Atom, cont_LeftContext());
+  }
+}
+
+void  clause_DeleteFlatFromIndex(CLAUSE Clause, st_INDEX Index)
+/**********************************************************
+  INPUT:   An unshared clause and an index.
+  EFFECT:  The clause is deleted from the index and deleted itself.
+***********************************************************/
+{
+  int     i,n;
+  LITERAL Lit;
+  TERM    Atom    ;
+
+  n = clause_Length(Clause);
+
+  for (i=clause_FirstLitIndex();i<n;i++) {
+    Lit  = clause_GetLiteral(Clause,i);
+    Atom = clause_LiteralAtom(Lit);
+    list_Delete(term_SupertermList(Atom));
+    term_RplacSupertermList(Atom, list_Nil());
+    st_EntryDelete(Index, Atom, Atom, cont_LeftContext());
+  }
+  clause_Delete(Clause);
+}
+
+
+void  clause_DeleteClauseListFlatFromIndex(LIST Clauses, st_INDEX Index)
+/**********************************************************
+  INPUT:   An list of unshared clause and an index.
+  EFFECT:  The clauses are deleted from the index and deleted itself.
+           The list is deleted.
+***********************************************************/
+{
+  LIST Scan;
+
+  for (Scan=Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan))
+    clause_DeleteFlatFromIndex(list_Car(Scan), Index);
+  
+  list_Delete(Clauses);
+}
+
+
+/******************************************************************/
+/* Some special functions used by hyper inference/reduction rules */
+/******************************************************************/
+
+static void clause_VarToSizeMap(SUBST Subst, NAT* Map, NAT MaxIndex)
+/**************************************************************
+  INPUT:   A substitution, an array <Map> of size <MaxIndex>+1.
+  RETURNS: Nothing.
+  EFFECT:  The index i within the array corresponds to the index
+           of a variable x_i. For each variable x_i, 0<=i<=MaxIndex
+           the size of its substitution term is calculated
+           and written to Map[i].
+***************************************************************/
+{
+  NAT *Scan;
+
+#ifdef CHECK
+  if (subst_Empty(Subst) || Map == NULL) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_VarToSizeMap: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  /* Initialization */
+  for (Scan = Map + MaxIndex; Scan >= Map; Scan--)
+    *Scan = 1;
+  /* Compute the size of substitution terms */
+  for ( ; !subst_Empty(Subst); Subst = subst_Next(Subst))
+    Map[subst_Dom(Subst)] = term_ComputeSize(subst_Cod(Subst));
+}
+
+
+static NAT clause_ComputeTermSize(TERM Term, NAT* VarMap)
+/**************************************************************
+  INPUT:   A term and a an array of NATs.
+  RETURNS: The number of symbols in the term.
+  EFFECT:  This function calculates the number of symbols in <Term>
+           with respect to some substitution s.
+           A naive way to do this is to apply the substitution
+           to a copy of the term, and to count the number of symbols
+           in the copied term.
+           We use a more sophisticated algorithm, that first stores
+	   the size of every variable's substitution term in <VarMap>.
+           We then 'scan' the term and for a variable occurrence x_i
+           we simply add the corresponding value VarMap[i] to the result.
+           This way we avoid copying the term and the substitution terms,
+           which is especially useful if we reuse the VarMap several times.
+***************************************************************/
+{
+  NAT Stack, Size;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_ComputeTermSize: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Size  = 0;
+  Stack = stack_Bottom();
+  do {
+    if (VarMap!=NULL && symbol_IsVariable(term_TopSymbol(Term)))
+      Size += VarMap[symbol_VarIndex(term_TopSymbol(Term))];
+    else {
+      Size++;
+      if (term_IsComplex(Term))
+        stack_Push(term_ArgumentList(Term));
+    }
+    while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+      stack_Pop();
+
+    if (!stack_Empty(Stack)) {
+      Term = list_Car(stack_Top());
+      stack_RplacTop(list_Cdr(stack_Top()));
+    }
+  } while (!stack_Empty(Stack));
+
+  return Size;
+}
+
+
+LIST clause_MoveBestLiteralToFront(LIST Literals, SUBST Subst, SYMBOL MaxVar,
+				   BOOL (*Better)(LITERAL, NAT, LITERAL, NAT))
+/**************************************************************
+  INPUT:   A list of literals, a substitution, the maximum variable
+           from the domain of the substitution, and a comparison
+	   function. The function <Better> will be called with two
+	   literals L1 and L2 and two number S1 and S2, where Si is
+	   the size of the atom of Li with respect to variable bindings
+	   in <Subst>.
+  RETURNS: The same list.
+  EFFECT:  This function moves the first literal L to the front of the
+           list, so that no other literal L' is better than L with respect
+	   to the function <Better>.
+	   The function exchanges only the literals, the order of list
+	   items within the list is not changed.
+***************************************************************/
+{
+  NAT  *Map, MapSize, BestSize, Size;
+  LIST Best, Scan;
+
+#ifdef CHECK
+  if (!list_IsSetOfPointers(Literals)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_MoveBestLiteralToFront: List contains duplicates");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (list_Empty(Literals) || list_Empty(list_Cdr(Literals)))
+    /* < 2 list items, so nothing to do */
+    return Literals;
+
+  Map     = NULL;
+  MapSize = 0;
+
+  if (!subst_Empty(Subst)) {
+    MapSize = symbol_VarIndex(MaxVar) + 1;
+    Map     = memory_Malloc(sizeof(NAT)*MapSize);
+    clause_VarToSizeMap(Subst, Map, MapSize-1);
+  }
+  Best     = Literals; /* Remember list item, not literal itself */
+  BestSize = clause_ComputeTermSize(clause_LiteralAtom(list_Car(Best)), Map);
+  for (Scan = list_Cdr(Literals); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    Size = clause_ComputeTermSize(clause_LiteralAtom(list_Car(Scan)), Map);
+    if (Better(list_Car(Scan), Size, list_Car(Best), BestSize)) {
+      /* Actual literal is better than the best encountered so far */
+      BestSize = Size;
+      Best     = Scan;
+    }
+  }
+  if (Best != Literals) {
+    /* Move best literal to the front. We just exchange the literals. */
+    LITERAL h = list_Car(Literals);
+    list_Rplaca(Literals, list_Car(Best));
+    list_Rplaca(Best, h);
+  }
+  /* cleanup */
+  if (Map != NULL)
+    memory_Free(Map, sizeof(NAT)*MapSize);
+
+  return Literals;
+}
+
+
+/**************************************************************/
+/* Literal Output Functions                                   */
+/**************************************************************/
+
+void clause_LiteralPrint(LITERAL Literal)
+/**************************************************************
+  INPUT:   A Literal.
+  RETURNS: Nothing.
+***************************************************************/
+{
+#ifdef CHECK
+  if (!clause_LiteralIsLiteral(Literal)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_LiteralPrint:");
+    misc_ErrorReport("\n Illegal input. Input not a literal.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  term_PrintPrefix(clause_LiteralSignedAtom(Literal));
+}
+
+
+void clause_LiteralListPrint(LIST LitList)
+/**************************************************************
+  INPUT:   A list of literals.
+  RETURNS: Nothing.
+  SUMMARY: Prints the literals  to stdout.
+***************************************************************/
+{
+  while (!(list_Empty(LitList))) {
+    clause_LiteralPrint(list_First(LitList));
+    LitList = list_Cdr(LitList);
+
+    if (!list_Empty(LitList))
+      putchar(' ');
+  }
+}
+
+
+void clause_LiteralPrintUnsigned(LITERAL Literal)
+/**************************************************************
+  INPUT:   A Literal.
+  RETURNS: Nothing.
+  SUMMARY:
+***************************************************************/
+{
+#ifdef CHECK
+  if (!clause_LiteralIsLiteral(Literal)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_LiteralPrintUnsigned:");
+    misc_ErrorReport("\n Illegal input. Input not a literal.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  term_PrintPrefix(clause_LiteralAtom(Literal));
+  fflush(stdout);
+}
+
+
+void clause_LiteralPrintSigned(LITERAL Literal)
+/**************************************************************
+  INPUT:   A Literal.
+  RETURNS: Nothing.
+  SUMMARY:
+***************************************************************/
+{
+#ifdef CHECK
+  if (!clause_LiteralIsLiteral(Literal)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_LiteralPrintSigned:");
+    misc_ErrorReport("\n Illegal input. Input not a literal.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  term_PrintPrefix(clause_LiteralSignedAtom(Literal));
+  fflush(stdout);
+}
+
+
+void clause_LiteralFPrint(FILE* File, LITERAL Lit)
+/**************************************************************
+  INPUT:   A file and a literal.
+  RETURNS: Nothing.
+************************************************************/
+{
+  term_FPrintPrefix(File, clause_LiteralSignedAtom(Lit));
+}
+
+
+LIST clause_GetLiteralSubSetList(CLAUSE Clause, int StartIndex, int EndIndex, 
+				 FLAGSTORE FlagStore, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, a start literal index, an end index, a
+           flag store and a precedence.
+  RETURNS: The list of literals between the start and the end 
+           index. 
+	   It is a list of pointers, not a list of indices.
+**************************************************************/
+{
+
+  LIST Result;
+  int  i;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, FlagStore, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_ReplaceLiteralSubSet:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+  if ((StartIndex < clause_FirstLitIndex())
+      || (EndIndex > clause_LastLitIndex(Clause))) {
+    misc_ErrorReport("\n In clause_ReplaceLiteralSubSet:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_ErrorReport("\n Index out of range.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Result = list_Nil();
+
+  for (i=StartIndex;
+       i<=EndIndex;
+       i++) {
+    Result = list_Cons(clause_GetLiteral(Clause, i), Result);
+  }
+
+  return Result;
+}
+
+
+void clause_ReplaceLiteralSubSet(CLAUSE Clause, int StartIndex, 
+				 int EndIndex, LIST Replacement,
+				 FLAGSTORE FlagStore, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, a start literal index, an end literal 
+           index, a flag store and a precedence.
+  RETURNS: None.
+  EFFECT:  Replaces the subset of literals in <Clause> with 
+           indices between (and including) <StartIndex> and
+	   <EndIndex> with literals from the <Replacement>
+	   list.
+**************************************************************/
+{
+
+  int i;
+  LIST Scan;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, FlagStore, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_ReplaceLiteralSubSet:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+  if ((StartIndex < clause_FirstLitIndex())
+      || (EndIndex > clause_LastLitIndex(Clause))) {
+    misc_ErrorReport("\n In clause_ReplaceLiteralSubSet:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_ErrorReport("\n Index out of range.");
+    misc_FinishErrorReport();
+  }
+  if (list_Length(Replacement) != (EndIndex - StartIndex + 1)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_ReplaceLiteralSubSet:");
+    misc_ErrorReport("\n Illegal input.  Replacement list size");
+    misc_ErrorReport("\n and set size don't match");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  for (i = StartIndex, Scan = Replacement; 
+       i <= EndIndex; 
+       i++, Scan = list_Cdr(Scan)) {
+    clause_SetLiteral(Clause, i, list_Car(Scan));
+  } 
+}
+
+static __inline__ BOOL clause_LiteralsCompare(LITERAL Left, LITERAL Right)
+/**************************************************************
+  INPUT:   Two literals.
+  RETURNS: TRUE if Left <= Right, FALSE otherwise.
+  EFFECT:  Compares literals by comparing their terms' arities.
+***************************************************************/
+{
+#ifdef CHECK
+  if (!(clause_LiteralIsLiteral(Left) && clause_LiteralIsLiteral(Right))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_LiteralsCompare:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  return term_CompareAbstractLEQ(clause_LiteralSignedAtom(Left),
+				 clause_LiteralSignedAtom(Right));
+}
+
+static __inline__ void clause_FixLiteralSubsetOrder(CLAUSE Clause, 
+						    int StartIndex, 
+						    int EndIndex,
+						    FLAGSTORE FlagStore,
+						    PRECEDENCE Precedence) 
+/**************************************************************
+  INPUT:   A clause, a start index, an end index a flag store
+           and a precedence.
+  RETURNS: None.
+  EFFECT:  Sorts literals with indices between (and including)
+           <StartIndex> and <EndIndex> with respect to an abstract
+	   list representation of terms that identifies function
+	   symbols with their arity.
+***************************************************************/
+{
+
+  LIST literals;
+
+#ifdef CHECK
+  if ((StartIndex < clause_FirstLitIndex())
+      || (EndIndex > clause_LastLitIndex(Clause))) {
+    misc_ErrorReport("\n In clause_FixLiteralSubSetOrder:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_ErrorReport("\n Index out of range.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  /* Get the literals */
+  literals = clause_GetLiteralSubSetList(Clause, StartIndex, EndIndex, FlagStore, Precedence);
+
+  /* Sort them */
+  literals = list_Sort(literals, (BOOL (*) (POINTER, POINTER)) clause_LiteralsCompare);
+
+  /* Replace clause literals in subset with sorted literals */
+  clause_ReplaceLiteralSubSet(Clause, StartIndex, EndIndex, literals, FlagStore, Precedence);
+
+  list_Delete(literals);
+}
+
+void clause_FixLiteralOrder(CLAUSE Clause, FLAGSTORE FlagStore, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, a flag store, and a precedence.
+  RETURNS: None.
+  EFFECT:  Fixes literal order in a <Clause>. Different literal
+           types are ordered separately.
+***************************************************************/
+{
+#ifdef CHECK
+  if (!clause_IsClause(Clause, FlagStore, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_FixLiteralOrder:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  /* Fix antecedent literal order */
+  clause_FixLiteralSubsetOrder(Clause,
+			       clause_FirstAntecedentLitIndex(Clause), 
+			       clause_LastAntecedentLitIndex(Clause),
+			       FlagStore, Precedence);
+
+  /* Fix succedent literal order */
+  clause_FixLiteralSubsetOrder(Clause,
+			       clause_FirstSuccedentLitIndex(Clause), 
+			       clause_LastSuccedentLitIndex(Clause),
+			       FlagStore, Precedence);
+
+  /* Fix constraint literal order */
+  clause_FixLiteralSubsetOrder(Clause,
+			       clause_FirstConstraintLitIndex(Clause), 
+			       clause_LastConstraintLitIndex(Clause),
+			       FlagStore, Precedence);  
+
+  /* Normalize clause, to get variable names right. */
+  clause_Normalize(Clause);
+}
+
+static int clause_CompareByWeight(CLAUSE Left, CLAUSE Right)
+/**************************************************************
+  INPUT:   Two clauses.
+  RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+  EFFECT:  Compares two clauses by their weight.
+***************************************************************/
+{
+  NAT lweight, rweight;
+  int result;
+
+  lweight = clause_Weight(Left);
+  rweight = clause_Weight(Right);
+
+  if (lweight < rweight) {
+    result = -1;
+  }
+  else if (lweight > rweight) {
+    result = 1;
+  }
+  else {
+    result = 0;
+  }
+
+  return result;
+}
+
+static int clause_CompareByClausePartSize(CLAUSE Left, CLAUSE Right) 
+/**************************************************************
+  INPUT:   Two clauses.
+  RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+  EFFECT:  Compares two clauses by the number of literals in
+           the antecedent, succedent and constraint.
+***************************************************************/
+{
+  int lsize, rsize;
+  
+  lsize = clause_NumOfAnteLits(Left);
+  rsize = clause_NumOfAnteLits(Right);
+  if (lsize < rsize)
+    return -1;
+  else if (lsize > rsize)
+    return 1;
+  
+  lsize = clause_NumOfSuccLits(Left);
+  rsize = clause_NumOfSuccLits(Right);
+  
+  if (lsize < rsize)
+    return -1;
+  else if (lsize > rsize)
+    return 1;
+  
+  lsize = clause_NumOfConsLits(Left);
+  rsize = clause_NumOfConsLits(Right);
+  
+  if (lsize < rsize)
+    return -1;
+  else if (lsize > rsize)
+    return 1;
+  
+  return 0;
+}
+
+void clause_CountSymbols(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A clause.
+  RETURNS: None.
+  EFFECT:  Counts the non-variable symbols in the clause, and 
+           increases their counts accordingly.
+***************************************************************/
+{
+  int i;
+
+  for (i=clause_FirstLitIndex(); i<=clause_LastLitIndex(Clause); i++) {
+    LITERAL l;
+    TERM    t;
+
+    l = clause_GetLiteral(Clause, i);
+    if (clause_LiteralIsPredicate(l)) {
+      SYMBOL S;
+
+      S = clause_LiteralPredicate(l);
+      symbol_SetCount(S, symbol_GetCount(S) + 1);
+    }
+
+    t = clause_GetLiteralAtom(Clause, i);
+
+    term_CountSymbols(t);
+  }
+}
+
+
+LIST clause_ListOfPredicates(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A clause.
+  RETURNS: A list of symbols.
+  EFFECT:  Creates a list of predicates occurring in the clause.
+           A predicate occurs several times in the list, if 
+	   it does so in the clause.
+***************************************************************/
+{
+  LIST preds;
+  int i;
+
+  preds = list_Nil();
+
+  for (i=clause_FirstLitIndex(); i<=clause_LastLitIndex(Clause); i++) {
+    LITERAL l;
+	
+    l = clause_GetLiteral(Clause, i);
+    if (clause_LiteralIsPredicate(l)) {
+      preds = list_Cons((POINTER) clause_LiteralPredicate(l), preds);
+    }
+  }
+
+  return preds;
+}
+
+LIST clause_ListOfConstants(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A clause.
+  RETURNS: A list of symbols.
+  EFFECT:  Creates a list of constants occurring in the clause.
+           A constant occurs several times in the list, if 
+	   it does so in the clause.
+***************************************************************/
+{
+  LIST consts;
+  int i;
+
+  consts = list_Nil();
+
+  for (i=clause_FirstLitIndex(); i<=clause_LastLitIndex(Clause); i++) {
+    TERM t;
+	
+    t = clause_GetLiteralAtom(Clause, i);
+
+    consts = list_Nconc(term_ListOfConstants(t), consts);
+  }
+
+  return consts;
+}
+
+LIST clause_ListOfVariables(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A clause.
+  RETURNS: A list of variables.
+  EFFECT:  Creates a list of variables occurring in the clause.
+           A variable occurs several times in the list, if 
+	   it does so in the clause.
+***************************************************************/
+{
+  LIST vars;
+  int i;
+
+  vars = list_Nil();
+
+  for (i=clause_FirstLitIndex(); i<=clause_LastLitIndex(Clause); i++) {
+    TERM t;
+	
+    t = clause_GetLiteralAtom(Clause, i);
+
+    vars = list_Nconc(term_ListOfVariables(t), vars);
+  }
+
+  return vars;
+}
+
+LIST clause_ListOfFunctions(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A clause.
+  RETURNS: A list of symbols.
+  EFFECT:  Creates a list of functions occurring in the clause.
+           A function occurs several times in the list, if 
+	   it does so in the clause.
+***************************************************************/
+{
+  LIST funs;
+  int i;
+
+  funs = list_Nil();
+
+  for (i=clause_FirstLitIndex(); i<=clause_LastLitIndex(Clause); i++) {
+    TERM t;
+	
+    t = clause_GetLiteralAtom(Clause, i);
+
+    funs = list_Nconc(term_ListOfFunctions(t), funs);
+  }
+
+  return funs;
+}
+
+static int clause_CompareByPredicateDistribution(CLAUSE Left, CLAUSE Right)
+/**************************************************************
+  INPUT:   Two clauses.
+  RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+  EFFECT:  Compares two clauses by the frequency of predicates.
+***************************************************************/
+{
+  LIST lpreds, rpreds;
+  int  result;
+
+  lpreds = clause_ListOfPredicates(Left);
+  rpreds = clause_ListOfPredicates(Right);
+
+  result = list_CompareMultisetsByElementDistribution(lpreds, rpreds);
+
+  list_Delete(lpreds);
+  list_Delete(rpreds);
+
+  return result;
+}
+
+static int clause_CompareByConstantDistribution(CLAUSE Left, CLAUSE Right)
+/**************************************************************
+  INPUT:   Two clauses.
+  RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+  EFFECT:  Compares two clauses by the frequency of constants.
+***************************************************************/
+{
+  LIST lconsts, rconsts;
+  int  result;
+
+  lconsts = clause_ListOfConstants(Left);
+  rconsts = clause_ListOfConstants(Right);
+
+  result = list_CompareMultisetsByElementDistribution(lconsts, rconsts);
+
+  list_Delete(lconsts);
+  list_Delete(rconsts);
+
+  return result;
+}
+
+static int clause_CompareByVariableDistribution(CLAUSE Left, CLAUSE Right)
+/**************************************************************
+  INPUT:   Two clauses.
+  RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+  EFFECT:  Compares two clauses by the frequency of variables.
+***************************************************************/
+{
+  LIST lvars, rvars;
+  int  result;
+
+  lvars = clause_ListOfVariables(Left);
+  rvars = clause_ListOfVariables(Right);
+
+  result = list_CompareMultisetsByElementDistribution(lvars, rvars);
+
+  list_Delete(lvars);
+  list_Delete(rvars);
+
+  return result;
+}
+
+static int clause_CompareByFunctionDistribution(CLAUSE Left, CLAUSE Right)
+/**************************************************************
+  INPUT:   Two clauses.
+  RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+  EFFECT:  Compares two clauses by the frequency of functions.
+***************************************************************/
+{
+  LIST lfuns, rfuns;
+  int  result;
+
+  lfuns = clause_ListOfFunctions(Left);
+  rfuns = clause_ListOfFunctions(Right);
+
+  result = list_CompareMultisetsByElementDistribution(lfuns, rfuns);
+
+  list_Delete(lfuns);
+  list_Delete(rfuns);
+
+  return result;
+}
+
+static int clause_CompareByDepth(CLAUSE Left, CLAUSE Right) 
+/**************************************************************
+  INPUT:   Two clauses.
+  RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+  EFFECT:  Compares two clauses by their depth.
+***************************************************************/
+{
+  if (clause_Depth(Left) < clause_Depth(Right))
+    return -1;
+  else if (clause_Depth(Left) > clause_Depth(Right))
+    return 1;
+
+  return 0;
+}
+
+static int clause_CompareByMaxVar(CLAUSE Left, CLAUSE Right)
+/**************************************************************
+  INPUT:   Two clauses.
+  RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+  EFFECT:  Compares two clauses by their maximal variable.
+***************************************************************/ 
+{
+  if (clause_MaxVar(Left) < clause_MaxVar(Right))
+    return -1;
+  else if (clause_MaxVar(Left) > clause_MaxVar(Right))
+    return 1;
+
+  return 0;
+}
+
+static int clause_CompareByLiterals(CLAUSE Left, CLAUSE Right) 
+/**************************************************************
+  INPUT:   Two clauses.
+  RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+  EFFECT:  Compares two clauses by comparing their literals 
+           from left to right.
+***************************************************************/
+{
+  int firstlitleft, lastlitleft;
+  int firstlitright, lastlitright;
+  int i, j;
+  int result;
+
+  result = 0;
+
+  /* Compare sorted literals from right to left */
+  
+  firstlitleft  = clause_FirstLitIndex();
+  lastlitleft   = clause_LastLitIndex(Left);
+  firstlitright = clause_FirstLitIndex();
+  lastlitright  = clause_LastLitIndex(Right);
+  
+  for (i = lastlitleft, j = lastlitright;
+       i >= firstlitleft && j >= firstlitright;
+       --i, --j) {
+    TERM lterm, rterm;
+    
+    lterm = clause_GetLiteralTerm(Left, i);
+    rterm = clause_GetLiteralTerm(Right, j);
+    
+    result = term_CompareAbstract(lterm, rterm);
+    
+    if (result != 0)
+      break;
+  }
+
+  if (result == 0) {
+    /* All literals compared equal, so check if someone has 
+       uncompared literals left over.
+    */
+    if ( i > j) {
+      /* Left clause has uncompared literals left over. */
+      result =  1;
+    }
+    else if (i < j) {
+      /* Right clause has uncompared literals left over. */
+      result = -1;
+    }
+  }
+
+  return result;
+}
+
+static int clause_CompareBySymbolOccurences(CLAUSE Left, CLAUSE Right) 
+/**************************************************************
+  INPUT:   Two clauses.
+  RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+  EFFECT:  Compares two clauses by comparing the occurrences of
+           symbols in their respective literals from left to 
+	   right. If a symbol occurs less frequently than
+	   its positional equivalent in the other clause,
+	   then the first clause is smaller.
+***************************************************************/
+{
+  int firstlitleft, lastlitleft;
+  int firstlitright, lastlitright;
+  int i, j;
+  int result;
+
+  result = 0;
+
+  /* Compare sorted literals from right to left */
+  
+  firstlitleft  = clause_FirstLitIndex();
+  lastlitleft   = clause_LastLitIndex(Left);
+  firstlitright = clause_FirstLitIndex();
+  lastlitright  = clause_LastLitIndex(Right);
+  
+  for (i = lastlitleft, j = lastlitright;
+       i >= firstlitleft && j >= firstlitright;
+       --i, --j) {
+    TERM lterm, rterm;
+    LITERAL llit, rlit;
+	
+    llit = clause_GetLiteral(Left, i);
+    rlit = clause_GetLiteral(Right, j);
+
+    if (clause_LiteralIsPredicate(llit)) {
+      if (clause_LiteralIsPredicate(rlit)) {
+	if (symbol_GetCount(clause_LiteralPredicate(llit)) 
+	    < symbol_GetCount(clause_LiteralPredicate(rlit))) {
+	  return -1;
+	}
+	else if (symbol_GetCount(clause_LiteralPredicate(llit)) 
+	    > symbol_GetCount(clause_LiteralPredicate(rlit))) {
+	  return 1;
+	}
+      }
+    }
+    
+    lterm = clause_GetLiteralTerm(Left, i);
+    rterm = clause_GetLiteralTerm(Right, j);
+    
+    result = term_CompareBySymbolOccurences(lterm, rterm);
+    
+    if (result != 0)
+      break;
+  }
+
+  return result;
+}
+
+int clause_CompareAbstract(CLAUSE Left, CLAUSE Right)
+/**************************************************************
+  INPUT:   Two clauses.
+  RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+  EFFECT:  Compares two clauses by their weight. If the weight
+           is equal, it compares the clauses by the arity of
+	   their literals from right to left.
+  CAUTION: Expects clause literal order to be fixed.
+***************************************************************/
+{
+
+  typedef int (*CLAUSE_COMPARE_FUNCTION) (CLAUSE, CLAUSE);
+
+  static const CLAUSE_COMPARE_FUNCTION clause_compare_functions [] = {
+    clause_CompareByWeight,
+    clause_CompareByDepth,
+    clause_CompareByMaxVar,
+    clause_CompareByClausePartSize,
+    clause_CompareByLiterals,
+    clause_CompareBySymbolOccurences,
+    clause_CompareByPredicateDistribution,
+    clause_CompareByConstantDistribution,
+    clause_CompareByFunctionDistribution,
+    clause_CompareByVariableDistribution,
+  };
+
+  int result;
+  int i;
+  int functions;
+
+  result    = 0;
+  functions = sizeof(clause_compare_functions)/sizeof(CLAUSE_COMPARE_FUNCTION);
+
+  for (i = 0; i < functions; i++) {
+    result = clause_compare_functions[i](Left, Right);
+
+    if ( result != 0) {
+      return result;
+    }
+  }
+
+  return 0;
+}
+
+
+/**************************************************************/
+/* Clause functions                                           */
+/**************************************************************/
+
+void clause_Init(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: Nothing.
+  SUMMARY: Initializes the clause counter and other variables
+           from this module.
+***************************************************************/
+{
+  int i;
+  clause_SetCounter(1);
+  clause_STAMPID = term_GetStampID();
+  for (i = 0; i <= clause_MAXWEIGHT; i++)
+    clause_SORT[i] = list_Nil();
+}
+
+
+CLAUSE clause_CreateBody(int ClauseLength)
+/**************************************************************
+  INPUT:   The number of literals as integer.
+  RETURNS: A new generated clause node for 'ClauseLength'
+  MEMORY:  Allocates a CLAUSE_NODE and the needed array for LITERALs.
+*************************************************************/
+{
+  CLAUSE Result;
+
+  Result                = (CLAUSE)memory_Malloc(sizeof(CLAUSE_NODE));
+
+  Result->clausenumber  = clause_IncreaseCounter();
+  Result->maxVar        = symbol_GetInitialStandardVarCounter();
+  Result->flags         = 0;
+  Result->depth         = 0;
+  clause_InitSplitData(Result);
+  Result->weight        = clause_WEIGHTUNDEFINED;
+  Result->parentCls     = list_Nil();
+  Result->parentLits    = list_Nil();
+
+  Result->c             = 0;
+  Result->a             = 0;
+  Result->s             = 0;
+
+  if (ClauseLength != 0)
+    Result->literals =
+      (LITERAL *)memory_Malloc((ClauseLength) * sizeof(LITERAL));
+
+  clause_SetFromInput(Result);
+
+  return Result;
+}
+
+
+CLAUSE clause_Create(LIST Constraint, LIST Antecedent, LIST Succedent,
+		     FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   Three lists of pointers to atoms, a flag store and 
+           a precedence.
+  RETURNS: The new generated clause.
+  MEMORY:  Allocates a CLAUSE_NODE and the needed LITERAL_NODEs,
+           uses the terms from the lists, additionally allocates
+	   termnodes for the fol_Not() in Const. and Ante.
+*************************************************************/
+{
+  CLAUSE Result;
+  int    i, c, a, s;
+  
+  Result                = (CLAUSE)memory_Malloc(sizeof(CLAUSE_NODE));
+  
+  Result->clausenumber  = clause_IncreaseCounter();
+  Result->flags         = 0;
+  Result->depth         = 0;
+  Result->weight        = clause_WEIGHTUNDEFINED;
+  clause_InitSplitData(Result);
+  Result->parentCls     = list_Nil();
+  Result->parentLits    = list_Nil();
+
+  Result->c             = (c = list_Length(Constraint));
+  Result->a             = (a = list_Length(Antecedent));
+  Result->s             = (s = list_Length(Succedent));
+
+  if (!clause_IsEmptyClause(Result))
+    Result->literals =
+      (LITERAL *) memory_Malloc((c+a+s) * sizeof(LITERAL));
+  
+  for (i = 0; i < c; i++) {
+    Result->literals[i] =
+      clause_LiteralCreate(term_Create(fol_Not(),
+	list_List((TERM)list_Car(Constraint))),Result);
+    Constraint = list_Cdr(Constraint);
+  }
+  
+  a += c;
+  for ( ; i < a; i++) {
+    Result->literals[i] =
+      clause_LiteralCreate(term_Create(fol_Not(),
+	list_List((TERM)list_Car(Antecedent))), Result);
+    Antecedent = list_Cdr(Antecedent);
+  }
+  
+  s += a;
+  for ( ; i < s; i++) {
+    Result->literals[i] =
+      clause_LiteralCreate((TERM) list_Car(Succedent), Result);
+    Succedent = list_Cdr(Succedent);
+  }
+  
+  clause_OrientAndReInit(Result, Flags, Precedence);
+  clause_SetFromInput(Result);
+  
+  return Result;
+}
+
+
+CLAUSE clause_CreateCrude(LIST Constraint, LIST Antecedent, LIST Succedent,
+			  BOOL Con)
+/**************************************************************
+  INPUT:   Three lists of pointers to literals (!) and a Flag indicating
+           whether the clause comes from the conjecture part of of problem.
+	   It is assumed that Constraint and Antecedent literals are negative,
+	   whereas Succedent literals are positive.
+  RETURNS: The new generated clause, where a clause_OrientAndReInit has still
+           to be performed, i.e., variables are not normalized, maximal literal
+	   flags not set, equations not oriented, the weight is not set.
+  MEMORY:  Allocates a CLAUSE_NODE and the needed LITERAL_NODEs,
+           uses the terms from the lists, additionally allocates
+	   termnodes for the fol_Not() in Const. and Ante.
+****************************************************************/
+{
+  CLAUSE Result;
+  int i,c,a,s;
+  
+  Result                = (CLAUSE)memory_Malloc(sizeof(CLAUSE_NODE));
+  
+  Result->clausenumber  = clause_IncreaseCounter();
+  Result->flags         = 0;
+  if (Con)
+    clause_SetFlag(Result, CONCLAUSE);
+
+  Result->depth         = 0;
+  Result->weight        = clause_WEIGHTUNDEFINED;
+  clause_InitSplitData(Result);
+  Result->parentCls     = list_Nil();
+  Result->parentLits    = list_Nil();
+
+  Result->c             = (c = list_Length(Constraint));
+  Result->a             = (a = list_Length(Antecedent));
+  Result->s             = (s = list_Length(Succedent));
+
+  if (!clause_IsEmptyClause(Result))
+    Result->literals = (LITERAL *)memory_Malloc((c+a+s) * sizeof(LITERAL));
+  
+  for (i = 0; i < c; i++) {
+    Result->literals[i] =
+      clause_LiteralCreate(list_Car(Constraint),Result);
+    Constraint = list_Cdr(Constraint);
+  }
+  
+  a += c;
+  for ( ; i < a; i++) {
+    Result->literals[i] =
+      clause_LiteralCreate(list_Car(Antecedent), Result);
+    Antecedent = list_Cdr(Antecedent);
+  }
+  
+  s += a;
+  for ( ; i < s; i++) {
+    Result->literals[i] = clause_LiteralCreate(list_Car(Succedent), Result);
+    Succedent = list_Cdr(Succedent);
+  }
+  
+  clause_SetFromInput(Result);
+  
+  return Result;
+}
+
+
+CLAUSE clause_CreateUnnormalized(LIST Constraint, LIST Antecedent,
+				 LIST Succedent)
+/**************************************************************
+  INPUT:   Three lists of pointers to atoms.
+  RETURNS: The new generated clause.
+  MEMORY:  Allocates a CLAUSE_NODE and the needed LITERAL_NODEs,
+           uses the terms from the lists, additionally allocates
+	   termnodes for the fol_Not() in Const. and Ante.
+  CAUTION: The weight of the clause is not set correctly and
+           equations are not oriented!
+****************************************************************/
+{
+  CLAUSE Result;
+  int i,c,a,s;
+
+  Result                = (CLAUSE)memory_Malloc(sizeof(CLAUSE_NODE));
+
+  Result->clausenumber  = clause_IncreaseCounter();
+  Result->flags         = 0;
+  Result->depth         = 0;
+  Result->weight        = clause_WEIGHTUNDEFINED;
+  clause_InitSplitData(Result);
+  Result->parentCls     = list_Nil();
+  Result->parentLits    = list_Nil();
+
+  Result->c             = (c = list_Length(Constraint));
+  Result->a             = (a = list_Length(Antecedent));
+  Result->s             = (s = list_Length(Succedent));
+
+  if (!clause_IsEmptyClause(Result)) {
+    Result->literals = (LITERAL *)memory_Malloc((c+a+s) * sizeof(LITERAL));
+  
+    for (i = 0; i < c; i++) {
+      Result->literals[i] =
+	clause_LiteralCreate(term_Create(fol_Not(),
+					 list_List(list_Car(Constraint))),
+			     Result);
+      Constraint = list_Cdr(Constraint);
+    }
+
+    a += c;
+    for ( ; i < a; i++) {
+      Result->literals[i]  =
+	clause_LiteralCreate(term_Create(fol_Not(),
+					 list_List(list_Car(Antecedent))),
+			     Result);
+      Antecedent = list_Cdr(Antecedent);
+    }
+
+    s += a;
+    for ( ; i < s; i++) {
+      Result->literals[i] =
+	clause_LiteralCreate((TERM)list_Car(Succedent), Result);
+      Succedent = list_Cdr(Succedent);
+    }
+    clause_UpdateMaxVar(Result);
+  }
+
+  return Result;
+}
+
+
+CLAUSE clause_CreateFromLiterals(LIST LitList, BOOL Sorts, BOOL Conclause,
+				 BOOL Ordering, FLAGSTORE Flags,
+				 PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A list of literals, three boolean flags indicating whether
+           sort constraint literals should be generated, whether the
+	   clause is a conjecture clause, whether the ordering information
+	   should be established, a flag store and a precedence.
+  RETURNS: The new generated clause.
+  EFFECT:  The result clause will be normalized and the maximal
+           variable will be set. If <Ordering> is FALSE no additional
+	   initializations will be done. This mode is intended for
+	   the parser for creating clauses at a time when the ordering
+	   and weight flags aren't determined finally.
+	   Only if <Ordering> is TRUE the equations will be oriented,
+	   the maximal literals will be marked and the clause weight
+	   will be set correctly.
+  MEMORY:  Allocates a CLAUSE_NODE and the needed LITERAL_NODEs,
+           uses the terms from the lists.
+****************************************************************/
+{
+  CLAUSE Result;
+  LIST   Antecedent,Succedent,Constraint;
+  TERM   Atom;
+
+  Antecedent = list_Nil();
+  Succedent  = list_Nil();
+  Constraint = list_Nil();
+
+  while (!list_Empty(LitList)) {
+    if (term_TopSymbol(list_Car(LitList)) == fol_Not()) {
+      Atom = term_FirstArgument(list_Car(LitList));
+      if (Sorts && symbol_IsBaseSort(term_TopSymbol(Atom)) && term_IsVariable(term_FirstArgument(Atom)))
+	Constraint = list_Cons(list_Car(LitList),Constraint);
+      else
+	Antecedent = list_Cons(list_Car(LitList),Antecedent);
+    }
+    else
+      Succedent = list_Cons(list_Car(LitList),Succedent);
+    LitList = list_Cdr(LitList);
+  }
+  
+  Constraint = list_NReverse(Constraint);
+  Antecedent = list_NReverse(Antecedent);
+  Succedent  = list_NReverse(Succedent);
+  Result = clause_CreateCrude(Constraint, Antecedent, Succedent, Conclause);
+
+  list_Delete(Constraint);
+  list_Delete(Antecedent);
+  list_Delete(Succedent);
+
+  if (Ordering)
+    clause_OrientAndReInit(Result, Flags, Precedence);
+  else {
+    clause_Normalize(Result);
+    clause_UpdateMaxVar(Result);
+  }
+  
+  return Result;
+}
+
+void clause_SetSortConstraint(CLAUSE Clause, BOOL Strong, FLAGSTORE Flags,
+			      PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, a flag indicating whether also negative
+           monadic literals with a real term argument should be
+	   put in the sort constraint, a flag store and a precedence.
+  RETURNS: Nothing.
+  EFFECT:  Negative monadic literals are put in the sort constraint.
+****************************************************************/
+{
+  LITERAL ActLit,Help;
+  TERM    ActAtom;
+  int     i,k,NewConLits;
+
+
+#ifdef CHECK
+  if (!clause_IsUnorderedClause(Clause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_SetSortConstraint:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  i          = clause_LastConstraintLitIndex(Clause);
+  NewConLits = 0;
+
+  for (k=clause_FirstAntecedentLitIndex(Clause);k<=clause_LastAntecedentLitIndex(Clause);k++) {
+    ActLit  = clause_GetLiteral(Clause,k);
+    ActAtom = clause_LiteralAtom(ActLit);
+    if (symbol_IsBaseSort(term_TopSymbol(ActAtom)) &&
+	(Strong || term_IsVariable(term_FirstArgument(ActAtom)))) {
+      if (++i != k) {
+	Help = clause_GetLiteral(Clause,i);
+	clause_SetLiteral(Clause,i,ActLit);
+	clause_SetLiteral(Clause,k,Help);
+      }
+      NewConLits++;
+    }
+  }
+
+  clause_SetNumOfConsLits(Clause, clause_NumOfConsLits(Clause) + NewConLits);
+  clause_SetNumOfAnteLits(Clause, clause_NumOfAnteLits(Clause) - NewConLits);
+  clause_ReInit(Clause, Flags, Precedence);
+
+#ifdef CHECK
+  if (!clause_IsUnorderedClause(Clause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_SetSortConstraint:");
+    misc_ErrorReport("\n Illegal computations.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+}
+
+
+
+void clause_Delete(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A Clause.
+  RETURNS: Nothing.
+  MEMORY:  Frees the memory of the clause.
+***************************************************************/
+{
+  int i, n;
+
+#ifdef CHECK
+  if (!clause_IsUnorderedClause(Clause)) { /* Clause may be a byproduct of some hyper rule */
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_Delete:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  n = clause_Length(Clause);
+  
+  for (i = 0; i < n; i++)
+    clause_LiteralDelete(clause_GetLiteral(Clause,i));
+
+  clause_FreeLitArray(Clause);
+  
+  list_Delete(clause_ParentClauses(Clause));
+  list_Delete(clause_ParentLiterals(Clause));
+#ifdef CHECK
+  if ((Clause->splitfield != NULL) && (Clause->splitfield_length == 0))
+    {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In clause_Delete:");
+      misc_ErrorReport("\n Illegal splitfield_length.");
+      misc_FinishErrorReport();
+    }
+  if ((Clause->splitfield == NULL) && (Clause->splitfield_length != 0))
+    {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In clause_Delete:");
+      misc_ErrorReport("\n Illegal splitfield.");
+      misc_FinishErrorReport();
+    }
+#endif
+  if (Clause->splitfield != NULL) {
+    
+    memory_Free(Clause->splitfield,
+		sizeof(SPLITFIELDENTRY) * Clause->splitfield_length);
+  }
+  clause_Free(Clause);
+}
+
+
+/**************************************************************/
+/* Functions to use the sharing for clauses.                  */
+/**************************************************************/
+
+void clause_InsertIntoSharing(CLAUSE Clause, SHARED_INDEX ShIndex,
+			      FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A Clause, an index, a flag store and a precedence.
+  RETURNS: Nothing.
+  SUMMARY: Inserts the unsigned atoms of 'Clause' into the sharing index.
+***************************************************************/
+{
+  int i, litnum;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_Delete:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+  clause_Check(Clause, Flags, Precedence);
+#endif
+
+  litnum = clause_Length(Clause);
+
+  for (i = 0; i < litnum; i++) {
+    clause_LiteralInsertIntoSharing(clause_GetLiteral(Clause,i), ShIndex);
+  }
+}
+
+
+void clause_DeleteFromSharing(CLAUSE Clause, SHARED_INDEX ShIndex,
+			      FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A Clause, an Index, a flag store and a precedence.
+  RETURNS: Nothing.
+  SUMMARY: Deletes 'Clause' and all its literals from the sharing,
+           frees the memory of 'Clause'.
+***************************************************************/
+{
+  int i, length;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_DeleteFromSharing:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  length = clause_Length(Clause);
+  
+  for (i = 0; i < length; i++)
+    clause_LiteralDeleteFromSharing(clause_GetLiteral(Clause,i),ShIndex);
+  
+  clause_FreeLitArray(Clause);
+  
+  list_Delete(clause_ParentClauses(Clause));
+  list_Delete(clause_ParentLiterals(Clause));
+#ifdef CHECK
+  if ((Clause->splitfield != NULL) && (Clause->splitfield_length == 0))
+    {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In clause_DeleteFromSharing:");
+      misc_ErrorReport("\n Illegal splitfield_length.");
+      misc_FinishErrorReport();
+    }
+  if ((Clause->splitfield == NULL) && (Clause->splitfield_length != 0))
+    {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In clause_DeleteFromSharing:");
+      misc_ErrorReport("\n Illegal splitfield.");
+      misc_FinishErrorReport();
+    }
+#endif
+  if (Clause->splitfield != NULL) {
+    memory_Free(Clause->splitfield,
+		sizeof(SPLITFIELDENTRY) * Clause->splitfield_length);
+  }
+  clause_Free(Clause);
+}
+
+
+void clause_MakeUnshared(CLAUSE Clause, SHARED_INDEX ShIndex)
+/**************************************************************
+  INPUT:   A Clause and an Index.
+  RETURNS: Nothing.
+  SUMMARY: Deletes the clauses literals from the sharing and
+           replaces them by unshared copies.
+***************************************************************/
+{
+  LITERAL ActLit;
+  TERM SharedAtom, AtomCopy;
+  int i,LastAnte,length;
+
+#ifdef CHECK
+  if (!clause_IsUnorderedClause(Clause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_MakeUnshared:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  LastAnte = clause_LastAntecedentLitIndex(Clause);
+  length   = clause_Length(Clause);
+
+  for (i = clause_FirstLitIndex(); i <= LastAnte; i++) {
+    ActLit     = clause_GetLiteral(Clause, i);
+    SharedAtom = clause_LiteralAtom(ActLit);
+    AtomCopy   = term_Copy(SharedAtom);
+    sharing_Delete(ActLit, SharedAtom, ShIndex);
+    clause_LiteralSetNegAtom(ActLit, AtomCopy);
+  }
+
+  for ( ; i < length; i++) {
+    ActLit     = clause_GetLiteral(Clause, i);
+    SharedAtom = clause_LiteralSignedAtom(ActLit);
+    AtomCopy   = term_Copy(SharedAtom);
+    sharing_Delete(ActLit, SharedAtom, ShIndex);
+    clause_LiteralSetPosAtom(ActLit, AtomCopy);
+  }
+}
+
+void clause_MoveSharedClause(CLAUSE Clause, SHARED_INDEX Source,
+			     SHARED_INDEX Destination, FLAGSTORE Flags,
+			     PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A Clause, two indexes, a flag store, and a precedence.
+  RETURNS: Nothing.
+  EFFECT:  Deletes <Clause> from <Source> and inserts it into 
+           <Destination>.
+***************************************************************/
+{
+  LITERAL Lit;
+  TERM    Atom,Copy;
+  int     i,length;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_MoveSharedClause:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  length   = clause_Length(Clause);
+
+  for (i = clause_FirstLitIndex(); i < length; i++) {
+    Lit  = clause_GetLiteral(Clause, i);
+    Atom = clause_LiteralAtom(Lit);
+    Copy = term_Copy(Atom);        /* sharing_Insert works destructively on <Copy>'s superterms */
+    clause_LiteralSetAtom(Lit, sharing_Insert(Lit, Copy, Destination));
+    sharing_Delete(Lit, Atom, Source);
+    term_Delete(Copy);
+  }
+}
+
+
+void clause_DeleteSharedLiteral(CLAUSE Clause, int Indice, SHARED_INDEX ShIndex, 
+				FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A Clause, a literals indice, an Index, a flag store
+           and a precedence.
+  RETURNS: Nothing.
+  SUMMARY: Deletes the shared literal from the clause.
+  MEMORY:  Various.
+***************************************************************/
+{
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_DeleteSharedLiteral:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  clause_MakeUnshared(Clause, ShIndex);
+  clause_DeleteLiteral(Clause, Indice, Flags, Precedence);
+  clause_InsertIntoSharing(Clause, ShIndex, Flags, Precedence);
+}
+
+
+void clause_DeleteClauseList(LIST ClauseList)
+/**************************************************************
+  INPUT:   A list of unshared clauses.
+  RETURNS: Nothing.
+  SUMMARY: Deletes all clauses in the list and the list.
+  MEMORY:  Frees the lists and the clauses' memory.
+ ***************************************************************/
+{
+  LIST Scan;
+
+  for (Scan = ClauseList; !list_Empty(Scan); Scan = list_Cdr(Scan))
+    if (clause_Exists(list_Car(Scan)))
+      clause_Delete(list_Car(Scan));
+
+  list_Delete(ClauseList);
+}
+
+
+void clause_DeleteSharedClauseList(LIST ClauseList, SHARED_INDEX ShIndex,
+				   FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A list of clauses, an index, a flag store and 
+           a precedence.
+  RETURNS: Nothing.
+  SUMMARY: Deletes all clauses in the list from the sharing.
+  MEMORY:  Frees the lists and the clauses' memory.
+***************************************************************/
+{
+  LIST Scan;
+
+  for (Scan = ClauseList; !list_Empty(Scan); Scan = list_Cdr(Scan))
+    clause_DeleteFromSharing(list_Car(Scan), ShIndex, Flags, Precedence);
+
+  list_Delete(ClauseList);
+}
+
+
+void clause_DeleteAllIndexedClauses(SHARED_INDEX ShIndex, FLAGSTORE Flags,
+				    PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   An Index, a flag store and a precedence.
+  RETURNS: Nothing.
+  SUMMARY: Deletes all clauses' terms from the sharing, frees their
+           memory.
+  MEMORY:  Frees the memory of all clauses with terms in the index.
+***************************************************************/
+{
+  LIST TermList,DelList,Scan;
+  TERM NewVar;
+  SYMBOL NewVarSymbol;
+
+  NewVar = term_CreateStandardVariable();
+  NewVarSymbol = term_TopSymbol(NewVar);
+
+  TermList = st_GetInstance(cont_LeftContext(), sharing_Index(ShIndex), NewVar);
+  /* This should yield a list of all terms in the index
+     and thus the sharing. */
+
+  while (!list_Empty(TermList)) {
+
+    DelList = sharing_GetDataList(list_Car(TermList), ShIndex);
+
+    for (Scan = DelList;
+	 !list_Empty(Scan);
+	 Scan = list_Cdr(Scan))
+      list_Rplaca(Scan, clause_LiteralOwningClause(list_Car(Scan)));
+
+    DelList = list_PointerDeleteDuplicates(DelList);
+
+    for (Scan = DelList;
+	 !list_Empty(Scan);
+	 Scan = list_Cdr(Scan))
+      clause_DeleteFromSharing(list_Car(Scan), ShIndex, Flags, Precedence);
+
+    list_Delete(TermList);
+
+    TermList = st_GetInstance(cont_LeftContext(), sharing_Index(ShIndex), NewVar);
+
+    list_Delete(DelList);
+  }
+  term_Delete(NewVar);
+  symbol_Delete(NewVarSymbol);
+}
+
+
+void clause_PrintAllIndexedClauses(SHARED_INDEX ShIndex)
+/**************************************************************
+  INPUT:   An Index.
+  RETURNS: Nothing.
+  SUMMARY: Prints all indexed clauses to stdout.
+***************************************************************/
+{
+  LIST TermList,ClList,PrintList,Scan;
+  TERM NewVar;
+  SYMBOL NewVarSymbol;
+
+  NewVar = term_CreateStandardVariable();
+  NewVarSymbol = term_TopSymbol(NewVar);
+
+  TermList = st_GetInstance(cont_LeftContext(), sharing_Index(ShIndex), NewVar);
+  /* This should yield a list of all terms in the index
+     and thus the sharing. */
+
+  PrintList = list_Nil();
+
+  while (!list_Empty(TermList)) {
+
+    ClList = sharing_GetDataList(list_Car(TermList), ShIndex);
+
+    for (Scan = ClList;
+	 !list_Empty(Scan);
+	 Scan = list_Cdr(Scan))
+      list_Rplaca(Scan, clause_LiteralOwningClause(list_Car(Scan)));
+
+    PrintList = list_NPointerUnion(ClList, PrintList);
+
+    Scan = TermList;
+    TermList = list_Cdr(TermList);
+    list_Free(Scan);
+  }
+  clause_ListPrint(PrintList);
+
+  list_Delete(PrintList);
+
+  term_Delete(NewVar);
+  symbol_Delete(NewVarSymbol);
+}
+
+
+LIST clause_AllIndexedClauses(SHARED_INDEX ShIndex)
+/**************************************************************
+  INPUT:   An index
+  RETURNS: A list of all the clauses in the index
+  MEMORY:  Memory is allocated for the list nodes
+***************************************************************/
+{
+  LIST clauselist, scan;
+  clauselist = sharing_GetAllSuperTerms(ShIndex);
+  for (scan = clauselist; scan != list_Nil(); scan = list_Cdr(scan))
+    list_Rplaca(scan, clause_LiteralOwningClause(list_Car(scan)));
+  clauselist = list_PointerDeleteDuplicates(clauselist);
+  return clauselist;
+}
+
+
+/**************************************************************/
+/* Clause Access Functions                                    */
+/**************************************************************/
+
+void clause_DeleteLiteralNN(CLAUSE Clause, int Indice)
+/**************************************************************
+  INPUT:   An unshared clause, and a literal index.
+  RETURNS: Nothing.
+  EFFECT:  The literal is position <Indice> is deleted from <Clause>.
+           The clause isn't reinitialized afterwards.
+  MEMORY:  The memory of the literal with the 'Indice' and 
+           memory of its atom is freed.
+***************************************************************/
+{
+  int     i, lc, la, length, shift;
+  LITERAL *Literals;
+
+#ifdef CHECK
+  if (!clause_IsUnorderedClause(Clause) || (clause_Length(Clause) <= Indice) ||
+      Indice < 0) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_DeleteLiteral:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  lc     = clause_LastConstraintLitIndex(Clause);
+  la     = clause_LastAntecedentLitIndex(Clause);
+  length = clause_Length(Clause);
+
+  /* Create a new literal array */
+  if (length > 1)
+    Literals = (LITERAL*) memory_Malloc(sizeof(LITERAL) * (length-1));
+  else
+    Literals = (LITERAL*) NULL;
+
+  /* Copy literals to the new array */
+  shift = 0;
+  length--;  /* The loop iterates over the new array */
+  for (i = 0; i < length; i++) {
+    if (i == Indice)
+      shift = 1;
+    Literals[i] = Clause->literals[i+shift];
+  }
+
+  /* Free literal and old array and set new one */
+  clause_LiteralDelete(clause_GetLiteral(Clause, Indice));
+  clause_FreeLitArray(Clause);
+  Clause->literals = Literals;
+
+  /* Update clause */
+  if (Indice <= lc)
+    clause_SetNumOfConsLits(Clause, clause_NumOfConsLits(Clause) - 1);
+  else if (Indice <= la)
+    clause_SetNumOfAnteLits(Clause, clause_NumOfAnteLits(Clause) - 1);
+  else
+    clause_SetNumOfSuccLits(Clause, clause_NumOfSuccLits(Clause) - 1);
+  /* Mark the weight as undefined */
+  Clause->weight = clause_WEIGHTUNDEFINED;
+}
+
+
+void clause_DeleteLiteral(CLAUSE Clause, int Indice, FLAGSTORE Flags,
+			  PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   An unshared clause, a literals index, a flag store,
+           and a precedence.
+  RETURNS: Nothing.
+  EFFECT:  The literal at position <Indice> is deleted from <Clause>.
+           In contrast to the function clause_DeleteLiteralNN
+	   the clause is reinitialized afterwards.
+  MEMORY:  The memory of the literal with the 'Indice' and memory
+           of its atom is freed.
+***************************************************************/
+{
+  clause_DeleteLiteralNN(Clause, Indice);
+  clause_ReInit(Clause, Flags, Precedence);
+}
+
+
+void clause_DeleteLiterals(CLAUSE Clause, LIST Indices, FLAGSTORE Flags,
+			   PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   An unshared clause, a list of literal indices a
+           flag store and a precedence.
+  RETURNS: Nothing.
+  EFFECT:  The literals given by <Indices> are deleted.
+           The clause is reinitialized afterwards.
+  MEMORY:  The memory of the literals with the 'Indice' and
+           memory of its atom is freed.
+***************************************************************/
+{
+  LITERAL *NewLits;
+  int     i, j, nc, na, ns, lc, la, olength, nlength;
+
+#ifdef CHECK
+  LIST Scan;
+  if (!list_IsSetOfPointers(Indices)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_DeleteLiterals:");
+    misc_ErrorReport(" list contains duplicate indices.");
+    misc_FinishErrorReport();
+  }
+  /* check the literal indices */
+  for (Scan = Indices; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    i = (int) list_Car(Scan);
+    if (i < 0 || i > clause_LastLitIndex(Clause)) {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In clause_DeleteLiterals:");
+      misc_ErrorReport(" literal index %d is out ", i);
+      misc_ErrorReport(" of bounds");
+      misc_FinishErrorReport();
+    }
+  }
+#endif
+
+  nc = 0;
+  na = 0;
+  ns = 0;
+  lc = clause_LastConstraintLitIndex(Clause);
+  la = clause_LastAntecedentLitIndex(Clause);
+
+  olength = clause_Length(Clause);
+  nlength = olength - list_Length(Indices);
+
+  if (nlength != 0)
+    NewLits = (LITERAL*) memory_Malloc(sizeof(LITERAL) * nlength);
+  else
+    NewLits = (LITERAL*) NULL;
+
+  for (i=clause_FirstLitIndex(), j=clause_FirstLitIndex(); i < olength; i++)
+ 
+    if (list_PointerMember(Indices, (POINTER) i))
+      clause_LiteralDelete(clause_GetLiteral(Clause,i));
+    else {
+
+      NewLits[j++] = clause_GetLiteral(Clause,i);
+
+      if (i <= lc)
+	nc++;
+      else if (i <= la)
+	na++;
+      else
+	ns++;
+    }
+  clause_FreeLitArray(Clause);
+  Clause->literals = NewLits;
+
+  clause_SetNumOfConsLits(Clause, nc);
+  clause_SetNumOfAnteLits(Clause, na);
+  clause_SetNumOfSuccLits(Clause, ns);
+
+  clause_ReInit(Clause, Flags, Precedence);
+}
+
+
+/**************************************************************/
+/* Clause Comparisons                                         */
+/**************************************************************/
+
+BOOL clause_IsHornClause(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A clause.
+  RETURNS: The boolean value TRUE if 'Clause' is a hornclause
+           FALSE else.
+  ***************************************************************/
+{
+#ifdef CHECK
+  if (!clause_IsUnorderedClause(Clause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_IsHornClause:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+  return (clause_NumOfSuccLits(Clause) <= 1);
+}
+
+
+BOOL clause_HasTermSortConstraintLits(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A clause,
+  RETURNS: TRUE iff there is at least one sort constraint atom having
+           a term as its argument
+***************************************************************/
+{
+  int i,n;
+
+#ifdef CHECK
+  if (!clause_IsUnorderedClause(Clause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_HasTermSortConstraintLits:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  n = clause_LastConstraintLitIndex(Clause);
+
+  for (i = clause_FirstConstraintLitIndex(Clause); i <= n; i++)
+    if (!term_AllArgsAreVar(clause_GetLiteralAtom(Clause,i)))
+      return TRUE;
+
+  return FALSE;
+}
+
+
+BOOL clause_HasSolvedConstraint(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A clause.
+  RETURNS: The boolean value TRUE if 'Clause' has a solved
+           constraint, i.e. only variables as sort arguments,
+	   FALSE else.
+***************************************************************/
+{
+  int  i,c;
+  LIST CVars, LitVars;
+
+#ifdef CHECK
+  if (!clause_IsUnorderedClause(Clause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_HasSolvedConstraint:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  CVars = list_Nil();
+  c     = clause_NumOfConsLits(Clause);
+
+  if (c == 0)
+    return TRUE;
+
+  if (clause_HasTermSortConstraintLits(Clause))
+    return FALSE;
+
+  for (i = 0; i < c; i++)
+    CVars = list_NPointerUnion(term_VariableSymbols(clause_GetLiteralAtom(Clause, i)), CVars);
+
+  if (i == c) {
+    c       = clause_Length(Clause);
+    LitVars = list_Nil();
+
+    for ( ; i < c; i++)
+      LitVars = list_NPointerUnion(LitVars, term_VariableSymbols(clause_GetLiteralAtom(Clause, i)));
+    
+    if (list_Empty(CVars = list_NPointerDifference(CVars, LitVars))) {
+      list_Delete(LitVars);
+      return TRUE;
+    }
+    list_Delete(LitVars);
+  }
+
+  list_Delete(CVars);
+
+  return FALSE;
+}
+
+
+BOOL clause_HasSelectedLiteral(CLAUSE Clause, FLAGSTORE Flags,
+			       PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A Clause, a flag store and a precedence.
+  RETURNS: The boolean value TRUE iff <Clause> has a selected literal
+***************************************************************/
+{
+  int  i,negs;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_HasSelectedLiteral:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  negs = clause_LastAntecedentLitIndex(Clause);
+
+  for (i=clause_FirstAntecedentLitIndex(Clause); i <= negs; i++)
+    if (clause_LiteralGetFlag(clause_GetLiteral(Clause,i), LITSELECT))
+      return TRUE;
+
+  return FALSE;
+}
+
+
+BOOL clause_IsDeclarationClause(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A clause.
+  RETURNS: The boolean value TRUE, if 'Clause' has only variables
+           as arguments in constraint literals.
+***************************************************************/
+{
+  int     i,length;
+  LITERAL Lit;
+
+#ifdef CHECK
+  if (!clause_IsUnorderedClause(Clause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_IsDeclarationClause:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  if (!clause_HasSolvedConstraint(Clause))
+    return FALSE;
+
+  length = clause_Length(Clause);
+
+  for (i=clause_FirstSuccedentLitIndex(Clause);i<length;i++) {
+    Lit = clause_GetLiteral(Clause,i);
+    if (clause_LiteralIsMaximal(Lit) &&
+	symbol_IsBaseSort(term_TopSymbol(clause_LiteralSignedAtom(Lit))))
+      return TRUE;
+  }
+
+  return FALSE;
+}
+
+
+BOOL clause_IsSortTheoryClause(CLAUSE Clause, FLAGSTORE Flags,
+			       PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A Clause, a flag store and a precedence.
+  RETURNS: The boolean value TRUE, if 'Clause' has only variables
+           as arguments in constraint literals, no antecedent literals
+	   and exactly one monadic succedent literal.
+***************************************************************/
+{
+  LITERAL Lit;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_IsSortTheoryClause:");
+    misc_ErrorReport("\n Illegal input. Input not a clause.");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  if (clause_NumOfAnteLits(Clause) > 0 ||
+      clause_NumOfSuccLits(Clause) > 1 ||
+      !clause_HasSolvedConstraint(Clause))
+    return FALSE;
+
+  Lit = clause_GetLiteral(Clause,clause_FirstSuccedentLitIndex(Clause));
+  if (symbol_IsBaseSort(term_TopSymbol(clause_LiteralSignedAtom(Lit))))
+    return TRUE;
+
+  return FALSE;
+}
+
+BOOL clause_IsPotentialSortTheoryClause(CLAUSE Clause, FLAGSTORE Flags,
+					PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A Clause, a flag store and a precedence.
+  RETURNS: The boolean value TRUE, if 'Clause' has monadic literals
+           only variables as arguments in antecedent/constraint literals,
+	   no other antecedent literals and exactly one monadic succedent
+	   literal.
+***************************************************************/
+{
+  LITERAL Lit;
+  int     i;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_IsPotentialSortTheoryClause:");
+    misc_ErrorReport("\n Illegal input. Input not a clause.");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  if (clause_NumOfSuccLits(Clause) != 1)
+    return FALSE;
+
+  for (i=clause_FirstLitIndex();i<clause_FirstSuccedentLitIndex(Clause);i++) {
+    Lit = clause_GetLiteral(Clause,i);
+    if (!symbol_IsBaseSort(term_TopSymbol(clause_LiteralAtom(Lit))) ||
+	!term_IsVariable(term_FirstArgument(clause_LiteralAtom(Lit))))
+      return FALSE;
+  }
+
+  Lit = clause_GetLiteral(Clause,clause_FirstSuccedentLitIndex(Clause));
+  if (symbol_IsBaseSort(term_TopSymbol(clause_LiteralSignedAtom(Lit))))
+    return TRUE;
+
+  return FALSE;
+}
+
+
+BOOL clause_HasOnlyVarsInConstraint(CLAUSE Clause, FLAGSTORE Flags,
+				    PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A Clause, a flag store and a precedence.
+  RETURNS: The boolean value TRUE, if 'Clause' has only variables
+           as arguments in constraint literals.
+***************************************************************/
+{
+  int  i,nc;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_HasOnlyVarsInConstraint:");
+    misc_ErrorReport("\n Illegal input. Input not a clause.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  nc = clause_NumOfConsLits(Clause);
+
+  for (i = 0; i < nc && term_AllArgsAreVar(clause_GetLiteralAtom(Clause,i)); i++)
+    /* empty */;
+
+  return (i == nc);
+}
+
+
+BOOL clause_HasSortInSuccedent(CLAUSE Clause, FLAGSTORE Flags,
+			       PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A Clause, a flag store and a precedence.
+  RETURNS: The boolean value TRUE, if 'Clause' has a maximal succedent
+           sort literal; FALSE, else.
+***************************************************************/
+{
+  LITERAL Lit;
+  int     i,l;
+  BOOL    result = FALSE;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_HasSortInSuccedent:");
+    misc_ErrorReport("\n Illegal input. Input not a clause.");
+    misc_FinishErrorReport();
+  }
+#endif
+ 
+  l  = clause_Length(Clause);
+
+  for (i = clause_FirstSuccedentLitIndex(Clause); i < l && !result ; i++) {
+    Lit = clause_GetLiteral(Clause, i);
+    result = (symbol_Arity(term_TopSymbol(clause_LiteralAtom(Lit))) == 1);
+  }
+  return result;
+}
+
+
+BOOL clause_LitsHaveCommonVar(LITERAL Lit1, LITERAL Lit2)
+/**************************************************************
+  INPUT:   Two literals.
+  RETURNS: The boolean value TRUE, if 'Lit1' and 'Lit2' have
+           common variables, FALSE, else.
+***************************************************************/
+{
+  LIST Vars1, Vars2;
+  BOOL Result;
+
+  Vars1  = term_VariableSymbols(clause_LiteralAtom(Lit1));
+  Vars2  = term_VariableSymbols(clause_LiteralAtom(Lit2));
+  Result = list_HasIntersection(Vars1, Vars2);
+  list_Delete(Vars1);
+  list_Delete(Vars2);
+
+  return Result;
+}
+
+
+/**************************************************************/
+/* Clause Input and Output Functions                          */
+/**************************************************************/
+
+void clause_Print(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A Clause.
+  RETURNS: Nothing.
+  SUMMARY: The clause is printed to stdout.
+***************************************************************/
+{
+  RULE Origin;
+  LITERAL Lit;
+  int i,c,a,s;
+
+#ifdef CHECK
+  if (!clause_IsUnorderedClause(Clause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_Print:");
+    misc_ErrorReport("\n Illegal input. Input not a clause.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (!clause_Exists(Clause))
+    fputs("(CLAUSE)NULL", stdout);
+  else {
+    printf("%d",clause_Number(Clause));
+    
+    Origin = clause_Origin(Clause);
+    printf("[%d:", clause_SplitLevel(Clause));
+
+#ifdef CHECK
+    if (Clause->splitfield_length <= 1)
+      fputs("0.", stdout);
+    else
+      for (i=Clause->splitfield_length-1; i > 0; i--)
+	printf("%lu.", Clause->splitfield[i]);
+    if (Clause->splitfield_length == 0)
+      putchar('1');
+    else
+      printf("%lu", (Clause->splitfield[0] | 1));
+    printf(":%c%c:%c:%d:%d:", clause_GetFlag(Clause, CONCLAUSE) ? 'C' : 'A',
+	   clause_GetFlag(Clause, WORKEDOFF) ? 'W' : 'U',
+	   clause_GetFlag(Clause, NOPARAINTO) ? 'N' : 'P',
+	   clause_Weight(Clause), clause_Depth(Clause));
+#endif
+    
+    clause_PrintOrigin(Clause);
+    
+    if (Origin == INPUT) {
+      ;
+    } else  {      
+      putchar(':');
+      clause_PrintParentClauses(Clause);
+    }
+    putchar(']');
+
+    c = clause_NumOfConsLits(Clause);
+    a = clause_NumOfAnteLits(Clause);
+    s = clause_NumOfSuccLits(Clause);
+
+    for (i = 0; i < c; i++) {
+      putchar(' ');
+      Lit = clause_GetLiteral(Clause, i);
+      clause_LiteralPrintUnsigned(Lit);
+    }
+    fputs(" || ", stdout);
+
+    a += c;
+    for ( ; i < a; i++) {
+
+      Lit = clause_GetLiteral(Clause, i);
+      clause_LiteralPrintUnsigned(Lit);
+      if (clause_LiteralIsMaximal(Lit)) {
+	putchar('*');
+	if (clause_LiteralIsOrientedEquality(Lit))
+	  putchar('*');
+      }
+      if (clause_LiteralGetFlag(Lit,LITSELECT))
+	putchar('+');
+      if (i+1 < a)
+	putchar(' ');
+    }
+    fputs(" -> ",stdout);
+
+    s += a;
+    for ( ; i < s; i++) {
+
+      Lit = clause_GetLiteral(Clause, i);
+      clause_LiteralPrintUnsigned(Lit);
+      if (clause_LiteralIsMaximal(Lit)) {
+	putchar('*');
+	if (clause_LiteralIsOrientedEquality(Lit))
+	  putchar('*');
+      }
+#ifdef CHECK
+      if (clause_LiteralGetFlag(Lit,LITSELECT)) {
+	misc_StartErrorReport();
+	misc_ErrorReport("\n In clause_Print: Clause has selected positive literal.\n");
+	misc_FinishErrorReport();
+      }
+#endif
+      if (i+1 < s)
+	putchar(' ');
+    }
+    putchar('.');
+  }
+}
+
+
+void clause_PrintMaxLitsOnly(CLAUSE Clause, FLAGSTORE Flags,
+			     PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A Clause, a flag store and a precedence.
+  RETURNS: Nothing.
+  SUMMARY:
+***************************************************************/
+{
+  int i,c,a,s;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_PrinMaxLitsOnly:");
+    misc_ErrorReport("\n Illegal input. Input not a clause.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  c = clause_NumOfConsLits(Clause);
+  a = clause_NumOfAnteLits(Clause);
+  s = clause_NumOfSuccLits(Clause);
+
+  for (i = 0; i < c; i++) {
+    if (clause_LiteralIsMaximal(clause_GetLiteral(Clause, i)))
+      clause_LiteralPrint(clause_GetLiteral(Clause, i));
+    if (clause_LiteralGetFlag(clause_GetLiteral(Clause, i),STRICTMAXIMAL)) {
+      clause_LiteralPrint(clause_GetLiteral(Clause, i));
+      fputs("(strictly)", stdout);
+    }
+  }
+  fputs(" || ", stdout);
+  
+  a += c;
+  for ( ; i < a; i++) {
+    if (clause_LiteralIsMaximal(clause_GetLiteral(Clause, i)))
+      clause_LiteralPrint(clause_GetLiteral(Clause, i));
+    if (clause_LiteralGetFlag(clause_GetLiteral(Clause, i),STRICTMAXIMAL)) {
+      clause_LiteralPrint(clause_GetLiteral(Clause, i));
+      fputs("(strictly)", stdout);
+    }
+  }
+  fputs(" -> ", stdout);
+
+  s += a;
+  for ( ; i < s; i++) {
+    if (clause_LiteralIsMaximal(clause_GetLiteral(Clause, i)))
+      clause_LiteralPrint(clause_GetLiteral(Clause, i));
+    if (clause_LiteralGetFlag(clause_GetLiteral(Clause, i),STRICTMAXIMAL)) {
+      clause_LiteralPrint(clause_GetLiteral(Clause, i));
+      fputs("(strictly)", stdout);
+    }
+  }
+  puts(".");  /* with newline */
+}
+
+
+void clause_FPrint(FILE* File, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A file and a clause.
+  RETURNS: Nothing.
+  SUMMARY: Prints any clause to the file 'File'.
+  CAUTION: Uses the term_Output functions.
+***************************************************************/
+{
+  int i, c, a, s;
+
+  c = clause_NumOfConsLits(Clause);
+  a = clause_NumOfAnteLits(Clause);
+  s = clause_NumOfSuccLits(Clause);
+
+  for (i = 0; i < c; i++)
+    term_FPrint(File, clause_GetLiteralAtom(Clause, i));
+
+  fputs(" || ", stdout);
+
+  a += c;
+  for ( ; i < a; i++)
+    term_FPrint(File, clause_GetLiteralAtom(Clause, i));
+
+  fputs(" -> ", stdout);
+
+  s += a;
+  for ( ; i < s; i++)
+    term_FPrint(File, clause_GetLiteralAtom(Clause, i));
+  
+  putc('.', File);
+}
+
+
+void clause_ListPrint(LIST ClauseList)
+/**************************************************************
+  INPUT:   A list of clauses.
+  RETURNS: Nothing.
+  SUMMARY: Prints the clauses to stdout.
+  CAUTION: Uses the clause_Print function.
+***************************************************************/
+{
+  while (!(list_Empty(ClauseList))) {
+    clause_Print(list_First(ClauseList));
+    ClauseList = list_Cdr(ClauseList);
+    if (!list_Empty(ClauseList))
+      putchar('\n');
+  }
+}
+
+
+void clause_PrintParentClauses(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A Clause.
+  RETURNS: Nothing.
+  SUMMARY: Prints the clauses parentclauses and -literals to stdout.
+***************************************************************/
+{
+  LIST Scan1,Scan2;
+  
+  if (!list_Empty(clause_ParentClauses(Clause))) {
+    
+    Scan1 = clause_ParentClauses(Clause);
+    Scan2 = clause_ParentLiterals(Clause);
+    printf("%d.%d", (int)list_Car(Scan1), (int)list_Car(Scan2));
+    
+    for (Scan1 = list_Cdr(Scan1), Scan2 = list_Cdr(Scan2);
+	 !list_Empty(Scan1);
+	 Scan1 = list_Cdr(Scan1), Scan2 = list_Cdr(Scan2))
+      printf(",%d.%d", (int)list_Car(Scan1), (int)list_Car(Scan2));
+  }
+}
+
+
+RULE clause_GetOriginFromString(const char* RuleName)
+/**************************************************************
+  INPUT:   A string containing the abbreviated name of a rule.
+  RETURNS: The RULE corresponding to the <RuleName>.
+***************************************************************/
+{
+  if      (string_Equal(RuleName, "App")) return CLAUSE_DELETION;
+  else if (string_Equal(RuleName, "EmS")) return EMPTY_SORT;
+  else if (string_Equal(RuleName, "SoR")) return SORT_RESOLUTION;
+  else if (string_Equal(RuleName, "EqR")) return EQUALITY_RESOLUTION;
+  else if (string_Equal(RuleName, "EqF")) return EQUALITY_FACTORING;
+  else if (string_Equal(RuleName, "MPm")) return MERGING_PARAMODULATION;
+  else if (string_Equal(RuleName, "SpR")) return SUPERPOSITION_RIGHT;
+  else if (string_Equal(RuleName, "SPm")) return PARAMODULATION;
+  else if (string_Equal(RuleName, "OPm")) return ORDERED_PARAMODULATION;
+  else if (string_Equal(RuleName, "SpL")) return SUPERPOSITION_LEFT;
+  else if (string_Equal(RuleName, "Res")) return GENERAL_RESOLUTION;
+  else if (string_Equal(RuleName, "SHy")) return SIMPLE_HYPER;
+  else if (string_Equal(RuleName, "OHy")) return ORDERED_HYPER;
+  else if (string_Equal(RuleName, "URR")) return UR_RESOLUTION;
+  else if (string_Equal(RuleName, "Fac")) return GENERAL_FACTORING;
+  else if (string_Equal(RuleName, "Spt")) return SPLITTING;
+  else if (string_Equal(RuleName, "Inp")) return INPUT;
+  else if (string_Equal(RuleName, "Rew")) return REWRITING;
+  else if (string_Equal(RuleName, "CRw")) return CONTEXTUAL_REWRITING;
+  else if (string_Equal(RuleName, "Con")) return CONDENSING;
+  else if (string_Equal(RuleName, "AED")) return ASSIGNMENT_EQUATION_DELETION;
+  else if (string_Equal(RuleName, "Obv")) return OBVIOUS_REDUCTIONS;
+  else if (string_Equal(RuleName, "SSi")) return SORT_SIMPLIFICATION;
+  else if (string_Equal(RuleName, "MRR")) return MATCHING_REPLACEMENT_RESOLUTION;
+  else if (string_Equal(RuleName, "UnC")) return UNIT_CONFLICT;
+  else if (string_Equal(RuleName, "Def")) return DEFAPPLICATION;
+  else if (string_Equal(RuleName, "Ter")) return TERMINATOR;
+  else {
+    misc_StartErrorReport();
+    misc_ErrorReport("\nIn clause_GetOriginFromString: Unknown clause origin.");
+    misc_FinishErrorReport();
+    return CLAUSE_DELETION; /* Just for the compiler, code is not reachable */
+  }
+}
+
+void clause_FPrintOrigin(FILE* File, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A Clause.
+  RETURNS: Nothing.
+  SUMMARY: Prints the clause's origin to the file.
+***************************************************************/
+{
+  RULE Result;
+
+  Result = clause_Origin(Clause);
+
+  switch(Result) {
+  case CLAUSE_DELETION:                 fputs("App", File); break;
+  case EMPTY_SORT:                      fputs("EmS", File); break;
+  case SORT_RESOLUTION:                 fputs("SoR", File); break;
+  case EQUALITY_RESOLUTION:             fputs("EqR", File); break;
+  case EQUALITY_FACTORING:              fputs("EqF", File); break;
+  case MERGING_PARAMODULATION:          fputs("MPm", File); break;
+  case SUPERPOSITION_RIGHT:             fputs("SpR", File); break;
+  case PARAMODULATION:                  fputs("SPm", File); break;
+  case ORDERED_PARAMODULATION:          fputs("OPm", File); break;
+  case SUPERPOSITION_LEFT:              fputs("SpL", File); break;
+  case GENERAL_RESOLUTION:              fputs("Res", File); break;
+  case SIMPLE_HYPER:                    fputs("SHy", File); break;
+  case ORDERED_HYPER:                   fputs("OHy", File); break;
+  case UR_RESOLUTION:                   fputs("URR", File); break;
+  case GENERAL_FACTORING:               fputs("Fac", File); break;
+  case SPLITTING:                       fputs("Spt", File); break;
+  case INPUT:                           fputs("Inp", File); break;
+  case REWRITING:                       fputs("Rew", File); break;
+  case CONTEXTUAL_REWRITING:            fputs("CRw", File); break;
+  case CONDENSING:                      fputs("Con", File); break;
+  case ASSIGNMENT_EQUATION_DELETION:    fputs("AED", File); break;
+  case OBVIOUS_REDUCTIONS:              fputs("Obv", File); break;
+  case SORT_SIMPLIFICATION:             fputs("SSi", File); break;
+  case MATCHING_REPLACEMENT_RESOLUTION: fputs("MRR", File); break;
+  case UNIT_CONFLICT:                   fputs("UnC", File); break;
+  case DEFAPPLICATION:                  fputs("Def", File); break;
+  case TERMINATOR:                      fputs("Ter", File); break;
+  case TEMPORARY:                       fputs("Temporary", File); break;
+  default:
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_FPrintOrigin: Clause has no origin.");
+    misc_FinishErrorReport();
+  }
+}
+
+
+void clause_PrintOrigin(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A Clause.
+  RETURNS: Nothing.
+  SUMMARY: Prints the clauses origin to stdout.
+***************************************************************/
+{
+  clause_FPrintOrigin(stdout, Clause);
+}
+
+
+void clause_PrintVerbose(CLAUSE Clause, FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A Clause, a flag store and a precedence.
+  RETURNS: Nothing.
+  SUMMARY: Prints almost all the information kept in the
+           clause structure.
+***************************************************************/
+{
+  int c,a,s;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_PrintVerbose:");
+    misc_ErrorReport("\n Illegal input. Input not a clause.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  c = clause_NumOfConsLits(Clause);
+  a = clause_NumOfAnteLits(Clause);
+  s = clause_NumOfSuccLits(Clause);
+
+  printf(" c = %d a = %d s = %d", c,a,s);
+  printf(" Weight : %d", clause_Weight(Clause));
+  printf(" Depth  : %d", clause_Depth(Clause));
+  printf(" %s %s ",
+	 (clause_GetFlag(Clause,WORKEDOFF) ? "WorkedOff" : "Usable"),
+	 (clause_GetFlag(Clause,CLAUSESELECT) ? "Selected" : "NotSelected"));
+
+  clause_Print(Clause);
+}
+
+
+CLAUSE clause_GetNumberedCl(int number, LIST ClList)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  CAUTION: 
+***************************************************************/
+{
+  while (!list_Empty(ClList) &&
+	 clause_Number((CLAUSE)list_Car(ClList)) != number)
+    ClList = list_Cdr(ClList);
+  
+  if (list_Empty(ClList))
+    return NULL;
+  else
+    return list_Car(ClList);
+}
+
+static __inline__ BOOL clause_NumberLower(CLAUSE A, CLAUSE B)
+{
+  return (BOOL) (clause_Number(A) < clause_Number(B));
+}
+
+LIST clause_NumberSort(LIST List)
+/**************************************************************
+  INPUT:   A list of clauses.
+  RETURNS: The same list where the elements are sorted wrt their number.
+  CAUTION: Destructive.
+***************************************************************/
+{
+  return list_Sort(List, (BOOL (*) (POINTER, POINTER)) clause_NumberLower);
+}
+
+
+LIST clause_NumberDelete(LIST List, int Number)
+/**************************************************************
+  INPUT:   A list of clauses and an integer.
+  RETURNS: The same list where the clauses with <Number> are deleted.
+  CAUTION: Destructive.
+***************************************************************/
+{
+  LIST Scan1,Scan2;
+  
+  for (Scan1 = List; !list_Empty(Scan1); )
+    if (clause_Number(list_Car(Scan1))==Number) {
+      
+      Scan2 = Scan1;
+      Scan1 = list_Cdr(Scan1);
+      List  = list_PointerDeleteOneElement(List, list_Car(Scan2));
+    } else
+      Scan1 = list_Cdr(Scan1);
+
+  return List;
+}
+
+
+static NAT clause_NumberOfMaxLits(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A clause.
+  RETURNS: The number of maximal literals in a clause.
+***************************************************************/
+{
+  NAT Result,i,n;
+
+  Result = 0;
+  n      = clause_Length(Clause);
+
+  for (i = clause_FirstAntecedentLitIndex(Clause); i < n; i++)
+    if (clause_LiteralIsMaximal(clause_GetLiteral(Clause,i)))
+      Result++;
+
+  return Result;
+}
+
+/* Unused ! */
+NAT clause_NumberOfMaxAntecedentLits(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A clause.
+  RETURNS: The number of maximal antecedent literals in a clause.
+***************************************************************/
+{
+  NAT Result,i,n;
+
+  Result = 0;
+  n      = clause_LastAntecedentLitIndex(Clause);
+
+  for (i = clause_FirstAntecedentLitIndex(Clause); i <= n; i++)
+    if (clause_LiteralIsMaximal(clause_GetLiteral(Clause,i)))
+      Result++;
+
+  return Result;
+}
+
+
+void clause_SelectLiteral(CLAUSE Clause, FLAGSTORE Flags)
+/**************************************************************
+  INPUT:   A clause and a flag store.
+  RETURNS: Nothing.
+  EFFECT:  If the clause contains more than 2 maximal literals,
+           at least one antecedent literal, the literal with
+	   the highest weight is selected.
+***************************************************************/
+{
+  if (clause_HasSolvedConstraint(Clause) &&
+      !clause_GetFlag(Clause,CLAUSESELECT) &&
+      clause_NumOfAnteLits(Clause) > 0 &&
+      (flag_GetFlagValue(Flags, flag_SELECT) == flag_SELECTALWAYS ||
+       (flag_GetFlagValue(Flags, flag_SELECT) == flag_SELECTIFSEVERALMAXIMAL &&
+	clause_NumberOfMaxLits(Clause) > 1))) {
+    NAT     i,n;
+    LITERAL Lit;
+    
+    n   = clause_LastAntecedentLitIndex(Clause);
+    i   = clause_FirstAntecedentLitIndex(Clause);
+    Lit = clause_GetLiteral(Clause,i);
+    i++;
+    
+    for ( ; i <= n; i++)
+      if (clause_LiteralWeight(Lit)
+	  < clause_LiteralWeight(clause_GetLiteral(Clause,i)))
+	Lit = clause_GetLiteral(Clause,i);
+    
+    clause_LiteralSetFlag(Lit,LITSELECT);
+    clause_SetFlag(Clause,CLAUSESELECT);
+  }
+}
+
+
+void clause_SetSpecialFlags(CLAUSE Clause, BOOL SortDecreasing, FLAGSTORE Flags,
+			    PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, a flag indicating whether all equations are
+           sort decreasing, a flag store and a precedence.
+  RETURNS: void.
+  EFFECT:  If the clause is a sort theory clause and its declaration
+           top symbol is a set declaration sort, i.e., it occurred in a
+	   declaration right from the beginning, the paramodulation/superposition
+	   steps into the clause are forbidden by setting the
+	   NOPARAINTO clause flag
+***************************************************************/
+{
+  if (SortDecreasing &&
+      clause_IsSortTheoryClause(Clause, Flags, Precedence) &&
+      symbol_HasProperty(term_TopSymbol(clause_GetLiteralTerm(Clause,clause_FirstSuccedentLitIndex(Clause))),
+			 DECLSORT))
+    clause_SetFlag(Clause,NOPARAINTO);
+}
+
+
+BOOL clause_ContainsPotPredDef(CLAUSE Clause, FLAGSTORE Flags,
+			       PRECEDENCE Precedence, NAT* Index, LIST* Pair)
+/**************************************************************
+  INPUT:   A clause, a flag store, a precedence and a pointer to an index.
+  RETURNS: TRUE iff a succedent literal of the clause is a predicate
+           having only variables as arguments, the predicate occurs only
+	   once in the clause and no other variables but the predicates'
+	   occur.
+	   In that case Index is set to the index of the predicate and
+	   Pair contains two lists : the literals for which positive
+	   occurrences must be found and a list of literals for which negative
+	   occurrences must be found for a complete definition.
+***************************************************************/
+{
+  NAT i;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_ContainsPotPredDef:");
+    misc_ErrorReport("\n Illegal input. Input not a clause.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  /* Iterate over all succedent literals */
+  for (i=clause_FirstSuccedentLitIndex(Clause); i < clause_Length(Clause); i++) {
+    LITERAL lit;
+    TERM atom;
+    LIST pair;
+
+    lit = clause_GetLiteral(Clause, i);
+    atom = clause_LiteralSignedAtom(lit);
+    if (symbol_IsPredicate(term_TopSymbol(atom))) {
+      LIST l;
+      BOOL ok;
+      ok = TRUE;
+      pair = list_PairCreate(list_Nil(), list_Nil());
+      
+      /* Make sure all arguments of predicate are variables */
+      for (l=term_ArgumentList(atom); !list_Empty(l); l=list_Cdr(l)) {
+	if (!term_IsStandardVariable((TERM) list_Car(l))) {
+	  ok = FALSE;
+	  break;
+	}
+      }
+      if (ok) {
+	/* Make sure predicate occurs only once in clause */
+	NAT j, count;
+	count = 0;
+	for (j=0; (j < clause_Length(Clause)) && (count < 2); j++) {
+	  TERM t;
+	  t = clause_GetLiteralAtom(Clause, j);
+	  if (symbol_Equal(term_TopSymbol(t), term_TopSymbol(atom)))
+	    count++;
+	}
+	if (count > 1)
+	  ok = FALSE;
+      }
+      if (ok) {
+	/* Build lists of positive and negative literals */
+	/* At the same time check if other variables than those among
+	   the predicates arguments are found */
+	NAT j;
+	LIST predvars, vars;
+	predvars = fol_FreeVariables(atom);
+	
+	/* Build list of literals for which positive occurrences are required */
+	for (j=0; (j < clause_FirstSuccedentLitIndex(Clause)) && ok; j++) {
+	  list_Rplaca(pair, list_Cons(clause_GetLiteralAtom(Clause, j), list_PairFirst(pair)));
+	  vars = fol_FreeVariables(clause_GetLiteralTerm(Clause, j));
+	  for (l = vars; !list_Empty(l); l = list_Cdr(l)) {
+	    if (!term_ListContainsTerm(predvars, list_Car(l))) {
+	      ok = FALSE;
+	      break;
+	    }
+	  }
+	  list_Delete(vars);
+	}
+	
+	/* Build list of literals for which negative occurrences are required */
+	for (j = clause_FirstSuccedentLitIndex(Clause);
+	     (j < clause_Length(Clause)) && ok; j++) {
+	  if (j != i) {
+	    list_Rplacd(pair, list_Cons(clause_GetLiteralAtom(Clause, j), list_PairSecond(pair)));
+	    vars = fol_FreeVariables(clause_GetLiteralAtom(Clause, j));
+	    for (l=vars; !list_Empty(l); l=list_Cdr(l)) {
+	      if (!term_ListContainsTerm(predvars, list_Car(l))) {
+		ok = FALSE;
+		break;
+	      }
+	    }
+	    list_Delete(vars);
+	  }
+	}
+	list_Delete(predvars);
+      }
+
+      if (ok) {
+	*Index = i;
+	*Pair = pair;
+	return TRUE;
+      }
+      else {
+	list_Delete(list_PairFirst(pair));
+	list_Delete(list_PairSecond(pair));
+	list_PairFree(pair);
+      }
+    }
+  }
+  return FALSE;
+}
+
+BOOL clause_IsPartOfDefinition(CLAUSE Clause, TERM Predicate, int *Index,
+			       LIST Pair)
+/**************************************************************
+  INPUT:   A clause, a term, a pointer to an int and a pair of term lists.
+  RETURNS: TRUE iff the predicate occurs among the negative literals of
+           the clause and the other negative and positive literals are found
+	   in the pairs' lists.
+	   In that case they are removed from the lists.
+	   Index is set to the index of the defined predicate in Clause.
+***************************************************************/
+{
+  NAT predindex, i;
+  BOOL ok;
+
+  ok = TRUE;
+
+  /* Check whether Predicate is among antecedent or constraint literals */
+  for (predindex=clause_FirstLitIndex();
+       predindex < clause_FirstSuccedentLitIndex(Clause);
+       predindex++)
+    if (term_Equal(Predicate, clause_GetLiteralAtom(Clause, predindex)))
+      break;
+  if (predindex == clause_FirstSuccedentLitIndex(Clause))
+    return FALSE;
+  *Index = predindex;
+
+  /* Check if other negative literals are required for definition */
+  for (i=clause_FirstLitIndex();
+       (i < clause_FirstSuccedentLitIndex(Clause)) && ok; i++) {
+    if (i != predindex)
+      if (!term_ListContainsTerm((LIST) list_PairSecond(Pair),
+				 clause_GetLiteralAtom(Clause, i)))
+	ok = FALSE;
+  }
+
+  /* Check if positive literals are required for definition */
+  for (i=clause_FirstSuccedentLitIndex(Clause);
+       (i < clause_Length(Clause)) && ok; i++)
+    if (!term_ListContainsTerm((LIST) list_PairFirst(Pair),
+			       clause_GetLiteralAtom(Clause, i)))
+      ok = FALSE;
+  
+  if (!ok)
+    return FALSE;
+  else {
+    /* Complement for definition found, remove literals from pair lists */
+    for (i=0; i < clause_FirstSuccedentLitIndex(Clause); i++)
+      if (i != predindex)
+	list_Rplacd(Pair,
+		    list_DeleteElement((LIST) list_PairSecond(Pair),
+				       clause_GetLiteralAtom(Clause, i),
+				       (BOOL (*)(POINTER, POINTER)) term_Equal));
+    for (i=clause_FirstSuccedentLitIndex(Clause); i < clause_Length(Clause); i++)
+      list_Rplaca(Pair,
+		  list_DeleteElement((LIST) list_PairFirst(Pair),
+				     clause_GetLiteralAtom(Clause, i),
+				     (BOOL (*)(POINTER, POINTER)) term_Equal));
+    return TRUE;
+  }
+}
+
+void clause_FPrintRule(FILE* File, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A file and a clause.
+  RETURNS: Nothing.
+  SUMMARY: Prints any term of the clause to file in rule format.
+  CAUTION: Uses the term_Output functions.
+***************************************************************/
+{
+  int  i,n;
+  TERM Literal;
+  LIST scan,antecedent,succedent,constraints;
+
+  n = clause_Length(Clause);
+
+  constraints = list_Nil();
+  antecedent  = list_Nil();
+  succedent   = list_Nil();
+
+  for (i = 0; i < n; i++) {
+    Literal = clause_GetLiteralTerm(Clause,i);
+    if (symbol_Equal(term_TopSymbol(Literal),fol_Not())) {
+      if (symbol_Arity(term_TopSymbol(fol_Atom(Literal))) == 1 &&
+	  symbol_IsVariable(term_TopSymbol(term_FirstArgument(fol_Atom(Literal)))))
+	constraints = list_Cons(Literal,constraints);
+      else
+	antecedent = list_Cons(Literal,antecedent);
+    }
+    else
+      succedent = list_Cons(Literal,succedent);
+  }
+
+  for (scan = constraints; !list_Empty(scan); scan = list_Cdr(scan)) {
+    term_FPrint(File, fol_Atom(list_Car(scan)));
+    putc(' ', File);
+  }
+  fputs("||", File);
+  for (scan = antecedent; !list_Empty(scan); scan = list_Cdr(scan)) {
+    putc(' ', File);
+    term_FPrint(File,fol_Atom(list_Car(scan)));
+    if (list_Empty(list_Cdr(scan)))
+      putc(' ', File);
+  }
+  fputs("->", File);
+  for (scan = succedent; !list_Empty(scan); scan = list_Cdr(scan)) {
+    putc(' ', File);
+    term_FPrint(File,list_Car(scan));
+  }
+  fputs(".\n", File);
+  
+  list_Delete(antecedent);
+  list_Delete(succedent);
+  list_Delete(constraints);
+}
+
+
+void clause_FPrintOtter(FILE* File, CLAUSE clause)
+/**************************************************************
+  INPUT:   A file and a clause.
+  RETURNS: Nothing.
+  SUMMARY: Prints any clause to File.
+  CAUTION: Uses the other clause_Output functions.
+***************************************************************/
+{
+  int     n,j;
+  LITERAL Lit;
+  TERM    Atom;
+  
+  n = clause_Length(clause);
+
+  if (n == 0)
+    fputs(" $F ", File);
+  else {
+    for (j = 0; j < n; j++) {
+      Lit  = clause_GetLiteral(clause,j);
+      Atom = clause_LiteralAtom(Lit);
+      if (clause_LiteralIsNegative(Lit))
+	putc('-', File);
+      if (fol_IsEquality(Atom)) {
+	if (clause_LiteralIsNegative(Lit))
+	  putc('(', File);
+	term_FPrintOtterPrefix(File,term_FirstArgument(Atom));
+	fputs(" = ", File);
+	term_FPrintOtterPrefix(File,term_SecondArgument(Atom));
+	if (clause_LiteralIsNegative(Lit))
+	  putc(')', File);
+      }
+      else
+	term_FPrintOtterPrefix(File,Atom);
+      if (j <= (n-2))
+	fputs(" | ", File);
+    }
+  }
+
+  fputs(".\n", File);
+}
+
+
+void clause_FPrintCnfDFG(FILE* File, BOOL OnlyProductive, LIST Axioms,
+			 LIST Conjectures, FLAGSTORE Flags,
+			 PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A file, a list of axiom clauses and a list of conjecture clauses.
+           A flag indicating whether only potentially productive clauses should
+	   be printed.
+	   A flag store.
+	   A precedence.
+  RETURNS: Nothing.
+  SUMMARY: Prints a  the respective clause lists to <File> dependent
+           on <OnlyProductive>.
+***************************************************************/
+{
+  LIST   scan;
+  CLAUSE Clause;
+
+  if (Axioms) {
+    fputs("list_of_clauses(axioms, cnf).\n", File);
+    for (scan=Axioms;!list_Empty(scan);scan=list_Cdr(scan)) {
+      Clause = (CLAUSE)list_Car(scan);
+      if (!OnlyProductive ||
+	  (clause_HasSolvedConstraint(Clause) &&
+	   !clause_HasSelectedLiteral(Clause, Flags, Precedence)))
+	clause_FPrintDFG(File,Clause,FALSE);
+    }
+    fputs("end_of_list.\n\n", File);
+  }
+
+  if (Conjectures) {
+    fputs("list_of_clauses(conjectures, cnf).\n", File);
+    for (scan=Conjectures;!list_Empty(scan);scan=list_Cdr(scan)) {
+      Clause = (CLAUSE)list_Car(scan);
+      if (!OnlyProductive ||
+	  (clause_HasSolvedConstraint(Clause) &&
+	   !clause_HasSelectedLiteral(Clause, Flags, Precedence)))
+	clause_FPrintDFG(File,Clause,FALSE);
+    }
+    fputs("end_of_list.\n\n", File);
+  }
+}
+
+
+static void clause_FPrintDescription(FILE* File, const char* Name,
+				     const char* Author, const char* Status,
+				     const char* Description)
+{
+  fputs("list_of_descriptions.\n", File);
+  fprintf(File, "name(%s).\n", Name);
+  fprintf(File, "author(%s).\n", Author);
+  fprintf(File, "status(%s).\n", Status);
+  fprintf(File, "description(%s).\n", Description);
+  fputs("end_of_list.\n", File);
+}
+
+void clause_FPrintCnfDFGProblem(FILE* File, const char* Name,
+				const char* Author, const char* Status,
+				const char* Description, LIST Clauses)
+/**************************************************************
+  INPUT:   A file, the problems name, author, status and description
+           to be included in the description block given as strings
+	   and a list of clauses.
+  RETURNS: Nothing.
+  SUMMARY: Prints a complete DFG problem clause file to <File>.
+***************************************************************/
+{
+  LIST Scan;
+
+  fputs("begin_problem(Unknown).\n\n", File);
+  clause_FPrintDescription(File, Name,  Author, Status,  Description);
+  putc('\n', File);
+  fputs("list_of_symbols.\n", File);
+  fol_FPrintDFGSignature(File);
+  fputs("end_of_list.\n\n", File);
+  fputs("list_of_clauses(axioms, cnf).\n", File);
+  
+  for (Scan=Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan))
+    if (!clause_GetFlag(list_Car(Scan),CONCLAUSE))
+      clause_FPrintDFG(File,list_Car(Scan),FALSE);
+
+  fputs("end_of_list.\n\n", File);
+  fputs("list_of_clauses(conjectures, cnf).\n", File);
+  
+  for (Scan=Clauses; !list_Empty(Scan); Scan=list_Cdr(Scan))
+    if (clause_GetFlag(list_Car(Scan),CONCLAUSE))
+      clause_FPrintDFG(File,list_Car(Scan),FALSE);
+ 
+  fputs("end_of_list.\n\n", File);
+  fputs("\nend_problem.\n\n", File);
+}
+
+
+void clause_FPrintCnfFormulasDFGProblem(FILE* File, BOOL OnlyProductive,
+					const char* Name, const char* Author,
+					const char* Status,
+					const char* Description, LIST Axioms,
+					LIST Conjectures, FLAGSTORE Flags,
+					PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A file, a list of axiom clauses and a list of conjecture clauses.
+           A flag indicating whether only potentially productive clauses should
+	   be printed.
+	   A bunch of strings that are printed to the description.
+	   A flag store.
+	   A precedence.
+  RETURNS: Nothing.
+  SUMMARY: Prints the respective clause lists as a complete DFG formulae output
+           to <File>.
+***************************************************************/
+{
+  LIST   scan;
+  CLAUSE Clause;
+
+  fputs("begin_problem(Unknown).\n\n", File);
+  clause_FPrintDescription(File, Name,  Author, Status,  Description);
+  fputs("\nlist_of_symbols.\n", File);
+  fol_FPrintDFGSignature(File);
+  fputs("end_of_list.\n\n", File);
+
+  if (Axioms) {
+    fputs("list_of_formulae(axioms).\n", File);
+    for (scan=Axioms; !list_Empty(scan); scan=list_Cdr(scan)) {
+      Clause = (CLAUSE)list_Car(scan);
+      if (!OnlyProductive ||
+	  (clause_HasSolvedConstraint(Clause) &&
+	   !clause_HasSelectedLiteral(Clause, Flags, Precedence)))
+	clause_FPrintFormulaDFG(File,Clause,FALSE);
+    }
+    fputs("end_of_list.\n\n", File);
+  }
+
+  if (Conjectures) {
+    fputs("list_of_formulae(conjectures).\n", File);
+    for (scan=Conjectures; !list_Empty(scan); scan=list_Cdr(scan)) {
+      Clause = (CLAUSE)list_Car(scan);
+      if (!OnlyProductive ||
+	  (clause_HasSolvedConstraint(Clause) &&
+	   !clause_HasSelectedLiteral(Clause, Flags, Precedence)))
+	clause_FPrintFormulaDFG(File,Clause,FALSE);
+    }
+    fputs("end_of_list.\n\n", File);
+  }
+
+  fputs("list_of_settings(SPASS).\n{*\n", File);
+  fol_FPrintPrecedence(File, Precedence);
+  fputs("\n*}\nend_of_list.\n\nend_problem.\n\n", File);
+}
+
+void clause_FPrintCnfOtter(FILE* File, LIST Clauses, FLAGSTORE Flags)
+/**************************************************************
+  INPUT:   A file, a list of clauses and a flag store.
+  RETURNS: Nothing.
+  SUMMARY: Prints the clauses to <File> in a format readable by Otter.
+***************************************************************/
+{
+  LIST   scan;
+  int    i;
+  BOOL   Equality;
+  CLAUSE Clause;
+
+  Equality = FALSE;
+
+  for (scan=Clauses;!list_Empty(scan) && !Equality; scan=list_Cdr(scan)) {
+    Clause = (CLAUSE)list_Car(scan);
+    for (i=clause_FirstAntecedentLitIndex(Clause);i<clause_Length(Clause);i++)
+      if (fol_IsEquality(clause_GetLiteralAtom(Clause,i))) {
+	Equality = TRUE;
+	i = clause_Length(Clause);
+      }
+  }
+
+  fol_FPrintOtterOptions(File, Equality,
+			 flag_GetFlagValue(Flags, flag_TDFG2OTTEROPTIONS));
+
+  if (Clauses) {
+    fputs("list(usable).\n", File);
+    if (Equality)
+      fputs("x=x.\n", File);
+    for (scan=Clauses;!list_Empty(scan);scan=list_Cdr(scan))
+      clause_FPrintOtter(File,list_Car(scan));
+    fputs("end_of_list.\n\n", File);
+  }
+}
+
+
+void clause_FPrintCnfDFGDerivables(FILE* File, LIST Clauses, BOOL Type)
+/**************************************************************
+  INPUT:   A file, a list of clauses and a bool flag Type.
+  RETURNS: Nothing.
+  SUMMARY: If <Type> is true then all axiom clauses in <Clauses> are
+	   written to <File>. Otherwise all conjecture clauses in
+	   <Clauses> are written to <File>.
+***************************************************************/
+{
+  CLAUSE Clause;
+
+  while (Clauses) {
+    Clause = (CLAUSE)list_Car(Clauses);
+    if ((Type && !clause_GetFlag(Clause,CONCLAUSE)) ||
+	(!Type && clause_GetFlag(Clause,CONCLAUSE)))
+      clause_FPrintDFG(File,Clause,FALSE);
+    Clauses = list_Cdr(Clauses);
+  }
+}
+
+
+void clause_FPrintDFGStep(FILE* File, CLAUSE Clause, BOOL Justif)
+/**************************************************************
+  INPUT:   A file, a clause and a boolean value.
+  RETURNS: Nothing.
+  SUMMARY: Prints any clause together with a label (the clause number)
+	   to File. If <Justif> is TRUE also the labels of the parent
+	   clauses are printed.
+  CAUTION: Uses the other clause_Output functions.
+***************************************************************/
+{
+  int     n,j;
+  LITERAL Lit;
+  TERM    Atom;
+  LIST    Variables,Iter;
+  
+  n = clause_Length(Clause);
+
+  fputs("  step(", File);
+  fprintf(File, "%d,", clause_Number(Clause));
+
+  Variables = list_Nil();
+
+  for (j = 0; j < n; j++)
+    Variables =
+      list_NPointerUnion(Variables,
+	term_VariableSymbols(clause_GetLiteralAtom(Clause,j)));
+
+  if (!list_Empty(Variables)) {
+    symbol_FPrint(File, fol_All());
+    fputs("([", File);
+    for (Iter = Variables; !list_Empty(Iter); Iter = list_Cdr(Iter)) {
+      symbol_FPrint(File, (SYMBOL) list_Car(Iter));
+      if (!list_Empty(list_Cdr(Iter)))
+	putc(',', File);
+    }
+    fputs("],", File);
+  }
+  
+  symbol_FPrint(File, fol_Or());
+  putc('(', File);
+
+  for (j = 0; j < n; j++) {
+    Lit  = clause_GetLiteral(Clause,j);
+    Atom = clause_LiteralSignedAtom(Lit);
+    term_FPrintPrefix(File,Atom);
+    if (j+1 < n)
+      putc(',', File);
+  }
+  if (n==0)
+    symbol_FPrint(File,fol_False());
+
+  if (!list_Empty(Variables)) {
+    list_Delete(Variables);
+    putc(')', File);
+  }
+  fputs("),", File);
+  clause_FPrintOrigin(File, Clause);
+
+  fputs(",[", File);
+  for (Iter = clause_ParentClauses(Clause);
+      !list_Empty(Iter);
+      Iter = list_Cdr(Iter)) {
+    fprintf(File, "%d", (int)list_Car(Iter));
+    if (!list_Empty(list_Cdr(Iter)))
+      putc(',', File);
+  }
+  putc(']', File);
+  fprintf(File, ",[splitlevel:%d]", clause_SplitLevel(Clause));
+  
+  fputs(").\n", File);
+}
+
+void clause_FPrintDFG(FILE* File, CLAUSE Clause, BOOL Justif)
+/**************************************************************
+  INPUT:   A file, a clause and a boolean value.
+  RETURNS: Nothing.
+  SUMMARY: Prints any clause together with a label (the clause number)
+	   to File. If Justif is TRUE also the labels of the parent
+	   clauses are printed.
+  CAUTION: Uses the other clause_Output functions.
+***************************************************************/
+{
+  int     n,j;
+  LITERAL Lit;
+  TERM    Atom;
+  LIST    Variables,Iter;
+  
+  n = clause_Length(Clause);
+
+  fputs("  clause(", File);
+  Variables = list_Nil();
+
+  for (j = 0; j < n; j++)
+    Variables =
+      list_NPointerUnion(Variables,
+	term_VariableSymbols(clause_GetLiteralAtom(Clause,j)));
+
+  if (!list_Empty(Variables)) {
+    symbol_FPrint(File, fol_All());
+    fputs("([", File);
+    for (Iter = Variables; !list_Empty(Iter); Iter = list_Cdr(Iter)) {
+      symbol_FPrint(File, (SYMBOL) list_Car(Iter));
+      if (!list_Empty(list_Cdr(Iter)))
+	putc(',', File);
+    }
+    fputs("],", File);
+  }
+  
+  symbol_FPrint(File, fol_Or());
+  putc('(', File);
+
+  for (j = 0; j < n; j++) {
+    Lit  = clause_GetLiteral(Clause,j);
+    Atom = clause_LiteralSignedAtom(Lit);
+    term_FPrintPrefix(File,Atom);
+    if (j+1 < n)
+      putc(',', File);
+  }
+  if (n==0)
+    symbol_FPrint(File,fol_False());
+
+  if (!list_Empty(Variables)) {
+    list_Delete(Variables);
+    putc(')', File);
+  }
+  fprintf(File, "),%d", clause_Number(Clause));
+
+  if (Justif) {
+    putc(',', File);
+    clause_FPrintOrigin(File, Clause);
+    fputs(",[", File);
+    for (Iter = clause_ParentClauses(Clause);
+	!list_Empty(Iter);
+	Iter = list_Cdr(Iter)) {
+      fprintf(File, "%d", (int)list_Car(Iter));
+      if (!list_Empty(list_Cdr(Iter)))
+	putc(',', File);
+    }
+    putc(']', File);
+    fprintf(File, ",%d", clause_SplitLevel(Clause));
+  }
+  
+  fputs(").\n", File);
+}
+
+void clause_FPrintFormulaDFG(FILE* File, CLAUSE Clause, BOOL Justif)
+/**************************************************************
+  INPUT:   A file, a clause and a boolean value.
+  RETURNS: Nothing.
+  SUMMARY: Prints any clause together with a label (the clause number)
+	   as DFG Formula to File. If Justif is TRUE also the labels of the
+	   parent clauses are printed.
+  CAUTION: Uses the other clause_Output functions.
+***************************************************************/
+{
+  int     n,j;
+  LITERAL Lit;
+  TERM    Atom;
+  LIST    Variables,Iter;
+  
+  n = clause_Length(Clause);
+
+  fputs("  formula(", File);
+  Variables = list_Nil();
+
+  for (j = 0; j < n; j++)
+    Variables =
+      list_NPointerUnion(Variables,
+	term_VariableSymbols(clause_GetLiteralAtom(Clause,j)));
+
+  if (!list_Empty(Variables)) {
+    symbol_FPrint(File, fol_All());
+    fputs("([", File);
+    for (Iter = Variables; !list_Empty(Iter); Iter = list_Cdr(Iter)) {
+      symbol_FPrint(File, (SYMBOL) list_Car(Iter));
+      if (!list_Empty(list_Cdr(Iter)))
+	putc(',', File);
+    }
+    fputs("],", File);
+  }
+  
+  if (n>1) {
+    symbol_FPrint(File, fol_Or());
+    putc('(', File);
+  }
+
+  for (j = 0; j < n; j++) {
+    Lit  = clause_GetLiteral(Clause,j);
+    Atom = clause_LiteralSignedAtom(Lit);
+    term_FPrintPrefix(File,Atom);
+    if (j+1 < n)
+      putc(',', File);
+  }
+  if (n==0)
+    symbol_FPrint(File,fol_False());
+
+  if (!list_Empty(Variables)) {
+    list_Delete(Variables);
+    putc(')', File);
+  }
+
+  if (n>1)
+    fprintf(File, "),%d", clause_Number(Clause));
+  else
+    fprintf(File, ",%d", clause_Number(Clause));
+
+  if (Justif) {
+    putc(',', File);
+    clause_FPrintOrigin(File, Clause);
+    fputs(",[", File);
+    for (Iter = clause_ParentClauses(Clause);
+	 !list_Empty(Iter);
+	 Iter = list_Cdr(Iter)) {
+      fprintf(File, "%d", (int)list_Car(Iter));
+      if (!list_Empty(list_Cdr(Iter)))
+	putc(',', File);
+    }
+    putc(']', File);
+    fprintf(File, ",%d", clause_SplitLevel(Clause));
+  }
+  
+  fputs(").\n", File);
+}
+
+
+void clause_Check(CLAUSE Clause, FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, a flag store and a precedence.
+  RETURNS: Nothing.
+  EFFECT:  Checks whether the clause is in a proper state. If
+           not, a core is dumped.
+***************************************************************/
+{
+  CLAUSE Copy;
+  if (!clause_Exists(Clause))
+    return;
+  
+  if (!clause_IsClause(Clause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_Check: Clause not consistent !\n");
+    misc_FinishErrorReport();
+  }
+
+  Copy = clause_Copy(Clause);
+  clause_OrientAndReInit(Copy, Flags, Precedence);
+  if ((clause_Weight(Clause) != clause_Weight(Copy)) ||
+      (clause_MaxVar(Clause) != clause_MaxVar(Copy))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_Check: Weight or maximal variable not properly set.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Delete(Copy);
+}
+
+/* The following are output procedures for clauses with parent pointers */
+
+
+void clause_PParentsFPrintParentClauses(FILE* File, CLAUSE Clause, BOOL ParentPts)
+/**************************************************************
+  INPUT:   A file, a clause and a boolean flag indicating whether
+           the clause's parents are given by numbers or pointers.
+  RETURNS: Nothing.
+  SUMMARY: Prints the clauses parent clauses and -literals to the file.
+           If <ParentPts> is TRUE the parent clauses are defined
+           by pointers, else by numbers.
+***************************************************************/
+{
+  LIST Scan1,Scan2;
+  int  length;
+  int  ParentNum;
+  
+  if (!list_Empty(clause_ParentClauses(Clause))) {
+    
+    Scan1 = clause_ParentClauses(Clause);
+    Scan2 = clause_ParentLiterals(Clause);
+    
+    if (ParentPts)
+      ParentNum = clause_Number(list_Car(Scan1));
+    else
+      ParentNum = (int)list_Car(Scan1);
+
+    fprintf(File, "%d.%d", ParentNum, (int)list_Car(Scan2));
+    
+    if (!list_Empty(list_Cdr(Scan1))) {
+      
+      length = list_Length(Scan1) - 2;
+      putc(',', File);
+      Scan1 = list_Cdr(Scan1);
+      Scan2 = list_Cdr(Scan2);
+      
+      if (ParentPts)
+	ParentNum = clause_Number(list_Car(Scan1));
+      else
+	ParentNum = (int)list_Car(Scan1);
+
+      fprintf(File, "%d.%d", ParentNum, (int)list_Car(Scan2));
+      
+      for (Scan1 = list_Cdr(Scan1), Scan2 = list_Cdr(Scan2);
+	   !list_Empty(Scan1);
+	   Scan1 = list_Cdr(Scan1), Scan2 = list_Cdr(Scan2)) {
+	
+	length -= 2;
+	
+	if (ParentPts)
+	  ParentNum = clause_Number(list_Car(Scan1));
+	else
+	  ParentNum = (int)list_Car(Scan1);
+
+	fprintf(File, ",%d.%d", ParentNum, (int)list_Car(Scan2));
+      }
+    }
+  }
+}
+
+void clause_PParentsLiteralFPrintUnsigned(FILE* File, LITERAL Literal)
+/**************************************************************
+  INPUT:   A Literal.
+  RETURNS: Nothing.
+  SUMMARY:
+***************************************************************/
+{
+#ifdef CHECK
+  if (!clause_LiteralIsLiteral(Literal)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_PParentsLiteralFPrintUnsigned:");
+    misc_ErrorReport("\n Illegal input. Input not a literal.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  term_FPrintPrefix(File, clause_LiteralAtom(Literal));
+  fflush(stdout);
+}
+
+void clause_PParentsFPrintGen(FILE* File, CLAUSE Clause, BOOL ParentPts)
+/**************************************************************
+  INPUT:   A file, a clause, a boolean flag.
+  RETURNS: Nothing.
+  EFFECTS: Prints the clause to file in SPASS format. If <ParentPts>
+           is TRUE, the parents of <Clause> are interpreted as pointers.
+***************************************************************/
+{
+  LITERAL Lit;
+  int i,c,a,s;
+
+  if (!clause_Exists(Clause))
+    fputs("(CLAUSE)NULL", File);
+  else {
+    fprintf(File, "%d",clause_Number(Clause));
+    
+    fprintf(File, "[%d:", clause_SplitLevel(Clause));
+
+#ifdef CHECK
+    if (Clause->splitfield_length <= 1)
+      fputs("0.", File);
+    else
+      for (i=Clause->splitfield_length-1; i > 0; i--)
+	fprintf(File, "%lu.", Clause->splitfield[i]);
+    if (Clause->splitfield_length == 0)
+      putc('1', File);
+    else
+      fprintf(File, "%lu", (Clause->splitfield[0] | 1));
+    fprintf(File,":%c%c:%c:%d:%d:", clause_GetFlag(Clause, CONCLAUSE) ? 'C' : 'A',
+	   clause_GetFlag(Clause, WORKEDOFF) ? 'W' : 'U',
+	   clause_GetFlag(Clause, NOPARAINTO) ? 'N' : 'P',
+	   clause_Weight(Clause), clause_Depth(Clause));
+#endif
+    
+    clause_FPrintOrigin(File, Clause);
+    
+    if (!list_Empty(clause_ParentClauses(Clause))) {
+      putc(':', File);
+      clause_PParentsFPrintParentClauses(File, Clause, ParentPts);
+    }
+    putc(']', File);
+
+    c = clause_NumOfConsLits(Clause);
+    a = clause_NumOfAnteLits(Clause);
+    s = clause_NumOfSuccLits(Clause);
+
+    for (i = 0; i < c; i++) {
+      Lit = clause_GetLiteral(Clause, i);
+      clause_PParentsLiteralFPrintUnsigned(File, Lit);
+      if (i+1 < c)
+	putc(' ', File);
+    }
+    fputs(" || ", File);
+
+    a += c;
+    for ( ; i < a; i++) {
+
+      Lit = clause_GetLiteral(Clause, i);
+      clause_PParentsLiteralFPrintUnsigned(File, Lit);
+      if (clause_LiteralIsMaximal(Lit)) {
+	putc('*', File);
+	if (clause_LiteralIsOrientedEquality(Lit))
+	  putc('*', File);
+      }
+      if (clause_LiteralGetFlag(Lit,LITSELECT))
+	putc('+', File);
+      if (i+1 < a)
+	putc(' ', File);
+    }
+    fputs(" -> ",File);
+
+    s += a;
+    for ( ; i < s; i++) {
+
+      Lit = clause_GetLiteral(Clause, i);
+      clause_PParentsLiteralFPrintUnsigned(File, Lit);
+      if (clause_LiteralIsMaximal(Lit)) {
+	putc('*', File);
+	if (clause_LiteralIsOrientedEquality(Lit))
+	  putc('*', File);
+      }
+#ifdef CHECK
+      if (clause_LiteralGetFlag(Lit, LITSELECT)) {
+	misc_StartErrorReport();
+	misc_ErrorReport("\n In clause_PParentsFPrintGen: Clause has selected positive literal.\n");
+	misc_FinishErrorReport();
+      }
+#endif
+      if (i+1 < s)
+	putc(' ', File);
+    }
+    putc('.', File);
+  }
+}
+
+void clause_PParentsFPrint(FILE* File, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A file handle and a clause.
+  RETURNS: Nothing.
+  EFFECTS: Prints out the clause to file in SPASS output format
+***************************************************************/
+{
+  clause_PParentsFPrintGen(File, Clause, TRUE);
+}
+
+void clause_PParentsListFPrint(FILE* File, LIST L)
+/**************************************************************
+ INPUT:   A file handle, a list of clauses with parent pointers
+ RETURNS: Nothing.
+ EFFECTS: Print the list to <file>.
+***************************************************************/
+{
+  while (!list_Empty(L)) {
+    clause_PParentsFPrint(File, list_Car(L));
+    putc('\n', File);
+    L = list_Cdr(L);
+  }
+}
+
+
+void clause_PParentsPrint(CLAUSE Clause)
+/**************************************************************
+ INPUT:   A clause with parent pointers
+ RETURNS: Nothing.
+ EFFECTS: The clause is printed to stdout.
+***************************************************************/
+{
+  clause_PParentsFPrint(stdout, Clause);
+}
+
+void clause_PParentsListPrint(LIST L)
+/**************************************************************
+ INPUT:   A file handle, a list of clauses with parent pointers
+ RETURNS: Nothing.
+ EFFECTS: Print the clause list to stdout.
+***************************************************************/
+{
+  clause_PParentsListFPrint(stdout, L);
+}
diff --git a/test/spass/clause.h b/test/spass/clause.h
new file mode 100644
index 0000000000000000000000000000000000000000..d163d35d614128479c88eb1a9774a0aedefc96d8
--- /dev/null
+++ b/test/spass/clause.h
@@ -0,0 +1,1589 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                   CLAUSES                              * */
+/* *                                                        * */
+/* *  $Module:   CLAUSE                                     * */
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                       * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _CLAUSE_
+#define _CLAUSE_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "sharing.h"
+#include "foldfg.h"
+#include "order.h"
+#include "subst.h"
+#include "flags.h"
+#include "symbol.h"
+
+/**************************************************************/
+/* Data Structures and Constants                              */
+/**************************************************************/
+
+/* Means weight of literal or clause is undefined */
+extern const NAT clause_WEIGHTUNDEFINED;
+
+extern int clause_CLAUSECOUNTER;
+
+typedef enum {MAXIMAL=1, STRICTMAXIMAL=2, LITSELECT=4} MAXFLAG;
+
+typedef enum {CLAUSE_DELETION, EMPTY_SORT, SORT_RESOLUTION,
+	      EQUALITY_RESOLUTION, EQUALITY_FACTORING, MERGING_PARAMODULATION,
+	      PARAMODULATION, ORDERED_PARAMODULATION,
+	      SUPERPOSITION_RIGHT,  SUPERPOSITION_LEFT,
+	      SIMPLE_HYPER, ORDERED_HYPER, UR_RESOLUTION,
+	      GENERAL_RESOLUTION, GENERAL_FACTORING, SPLITTING, INPUT,
+	      CONDENSING, ASSIGNMENT_EQUATION_DELETION, OBVIOUS_REDUCTIONS,
+	      SORT_SIMPLIFICATION, REWRITING, CONTEXTUAL_REWRITING,
+	      MATCHING_REPLACEMENT_RESOLUTION, UNIT_CONFLICT, DEFAPPLICATION,
+	      TERMINATOR, TEMPORARY
+} RULE;
+
+typedef unsigned long SPLITFIELDENTRY;
+typedef SPLITFIELDENTRY* SPLITFIELD;
+
+typedef enum  {WORKEDOFF=1,CLAUSESELECT=2,DOCCLAUSE=4,CONCLAUSE=8,BLOCKED=16,
+	       NOPARAINTO=32, MARKED=64, HIDDEN=128} CLAUSE_FLAGS;
+
+
+/* As there are a lot of implications a clauses properties may have */
+/* for the prover, this information should be kept with the clause. */
+/* That for a flagfield is foreseen, most likely an integer used    */
+/* like the sort-Bitfield existing for term, now used for varoccs.  */
+
+typedef struct CLAUSE_HELP{
+  int      clausenumber;
+  NAT      weight;     /* The sum of the weight of all literals */
+  NAT      depth;      /* The depth of the clause in the derivation  */
+  NAT      validlevel; /* Level of splitting where clause is valid. */
+  SPLITFIELD splitfield;
+  unsigned splitfield_length;
+  
+  LIST     parentCls, parentLits; /* Parents clauses' clause and lit numbers.*/
+  NAT      flags;
+  SYMBOL   maxVar;     /* The maximal variable symbol in the clause */
+  struct LITERAL_HELP{
+    NAT    maxLit;     /* for clause intern literal ordering */
+    NAT    weight;     /* weight of the <atomWithSign> below */
+    BOOL   oriented;   /* Flag, TRUE if clause is oriented, i.e. equalities
+			  with bigger first arg and all other predicates */
+    struct CLAUSE_HELP *owningClause;
+    TERM   atomWithSign; /* Pointer to the term, where an unshared
+			    Term for the sign of negative literals
+			    is supplied additionally.              */
+  } **literals;        /* An Array of (c+a+s) literalpointers in this order. */
+  int      c;          /* number of constraint literals */
+  int      a;          /* number of antecedent literals */
+  int	   s;          /* number of succedent literals */
+  RULE    origin;
+} *CLAUSE, CLAUSE_NODE;
+
+typedef struct LITERAL_HELP *LITERAL, LITERAL_NODE;
+
+
+/**************************************************************/
+/* Functions Prototypes                                       */
+/**************************************************************/
+
+/**************************************************************/
+/* Functions on clauses and literals creation and deletion.   */
+/**************************************************************/
+
+void    clause_Init(void);
+
+CLAUSE  clause_CreateBody(int);
+CLAUSE  clause_Create(LIST, LIST, LIST, FLAGSTORE, PRECEDENCE);
+CLAUSE  clause_CreateCrude(LIST, LIST, LIST, BOOL);
+CLAUSE  clause_CreateUnnormalized(LIST, LIST, LIST);
+CLAUSE  clause_CreateFromLiterals(LIST, BOOL, BOOL, BOOL, FLAGSTORE, PRECEDENCE);
+void    clause_Delete(CLAUSE);
+
+LITERAL clause_LiteralCreate(TERM, CLAUSE);
+LITERAL clause_LiteralCreateNegative(TERM, CLAUSE);        /* Unused */
+void    clause_LiteralDelete(LITERAL);
+
+LIST    clause_CopyConstraint(CLAUSE);
+LIST    clause_CopyAntecedentExcept(CLAUSE, int);
+LIST    clause_CopySuccedent(CLAUSE);
+LIST    clause_CopySuccedentExcept(CLAUSE, int);
+
+
+/**************************************************************/
+/* Functions to use the sharing for clauses and literals.     */
+/**************************************************************/
+
+void    clause_InsertIntoSharing(CLAUSE, SHARED_INDEX, FLAGSTORE, PRECEDENCE);
+void    clause_DeleteFromSharing(CLAUSE, SHARED_INDEX, FLAGSTORE, PRECEDENCE);
+
+void    clause_MakeUnshared(CLAUSE, SHARED_INDEX);
+void    clause_MoveSharedClause(CLAUSE, SHARED_INDEX, SHARED_INDEX, FLAGSTORE, PRECEDENCE);
+void    clause_DeleteSharedLiteral(CLAUSE, int, SHARED_INDEX, FLAGSTORE, PRECEDENCE);
+
+void    clause_LiteralInsertIntoSharing(LITERAL, SHARED_INDEX);
+void    clause_LiteralDeleteFromSharing(LITERAL, SHARED_INDEX);  /* Used only in clause.c */
+
+void    clause_DeleteClauseList(LIST);
+void    clause_DeleteSharedClauseList(LIST, SHARED_INDEX, FLAGSTORE, PRECEDENCE);
+void    clause_DeleteAllIndexedClauses(SHARED_INDEX, FLAGSTORE, PRECEDENCE); /* Necessary? */
+void    clause_PrintAllIndexedClauses(SHARED_INDEX);       /* For Debugging */
+LIST    clause_AllIndexedClauses(SHARED_INDEX);
+
+/**************************************************************/
+/* Clause Comparisons                                         */
+/**************************************************************/
+
+BOOL    clause_IsHornClause(CLAUSE);
+int     clause_CompareAbstract(CLAUSE, CLAUSE);
+
+/**************************************************************/
+/* Clause and literal Input and Output Functions              */
+/**************************************************************/
+
+void    clause_Print(CLAUSE);
+void    clause_PrintVerbose(CLAUSE, FLAGSTORE, PRECEDENCE);
+void    clause_PrintMaxLitsOnly(CLAUSE, FLAGSTORE, PRECEDENCE); /* For Debugging */
+void    clause_FPrint(FILE*, CLAUSE);                /* For Debugging */
+void    clause_FPrintRule(FILE*, CLAUSE);
+void    clause_FPrintOtter(FILE*, CLAUSE);           /* Unused */
+void    clause_FPrintCnfDFG(FILE* , BOOL, LIST, LIST, FLAGSTORE, PRECEDENCE);
+void    clause_FPrintCnfDFGProblem(FILE* , const char*, const char*, const char*, const char*, LIST);
+void    clause_FPrintCnfFormulasDFGProblem(FILE* , BOOL, const char*, const char*, const char*, const char*, LIST, LIST, FLAGSTORE, PRECEDENCE);
+void    clause_FPrintCnfDFGDerivables(FILE*, LIST, BOOL);
+void    clause_FPrintDFG(FILE*, CLAUSE, BOOL);
+void    clause_FPrintDFGStep(FILE*, CLAUSE, BOOL);
+void    clause_FPrintFormulaDFG(FILE*, CLAUSE, BOOL);
+void    clause_FPrintCnfOtter(FILE*, LIST, FLAGSTORE);
+
+void    clause_LiteralPrint(LITERAL);                /* For Debugging */
+void    clause_LiteralListPrint(LIST);               /* For Debugging */
+void    clause_LiteralPrintUnsigned(LITERAL);        /* For Debugging */
+void    clause_LiteralPrintSigned(LITERAL);          /* For Debugging */
+void    clause_LiteralFPrint(FILE*, LITERAL);        /* For Debugging */
+
+void    clause_ListPrint(LIST);
+
+void    clause_PrintParentClauses(CLAUSE);           /* For Debugging */
+void    clause_PrintOrigin(CLAUSE);                  /* For Debugging */
+void    clause_FPrintOrigin(FILE*, CLAUSE);
+
+/**************************************************************/
+/* Specials                                                   */
+/**************************************************************/
+
+CLAUSE  clause_Copy(CLAUSE);
+LITERAL clause_LiteralCopy(LITERAL);
+
+static __inline__ LIST clause_CopyClauseList(LIST List)
+{
+  return list_CopyWithElement(List, (POINTER (*)(POINTER)) clause_Copy);
+}
+
+void    clause_DeleteLiteral(CLAUSE, int, FLAGSTORE, PRECEDENCE);
+void    clause_DeleteLiteralNN(CLAUSE, int);
+void    clause_DeleteLiterals(CLAUSE, LIST, FLAGSTORE, PRECEDENCE);  /* Unused */
+LIST    clause_GetLiteralSubSetList(CLAUSE, int, int, FLAGSTORE, PRECEDENCE);
+void    clause_ReplaceLiteralSubSet(CLAUSE, int, int, LIST, FLAGSTORE, PRECEDENCE);
+void    clause_FixLiteralOrder(CLAUSE, FLAGSTORE, PRECEDENCE);
+
+SYMBOL  clause_AtomMaxVar(TERM);
+void    clause_SetMaxLitFlags(CLAUSE, FLAGSTORE, PRECEDENCE);
+SYMBOL  clause_LiteralMaxVar(LITERAL);        /* Used only in clause.c */
+SYMBOL  clause_SearchMaxVar(CLAUSE);
+void    clause_UpdateMaxVar(CLAUSE);
+
+void    clause_RenameVarsBiggerThan(CLAUSE, SYMBOL);
+void    clause_Normalize(CLAUSE);
+void    clause_SetSortConstraint(CLAUSE, BOOL, FLAGSTORE, PRECEDENCE);
+void    clause_SubstApply(SUBST, CLAUSE);
+void    clause_ReplaceVariable(CLAUSE, SYMBOL, TERM);
+void    clause_OrientEqualities(CLAUSE, FLAGSTORE, PRECEDENCE);
+NAT     clause_NumberOfVarOccs(CLAUSE);
+NAT     clause_NumberOfSymbolOccurrences(CLAUSE, SYMBOL);
+NAT     clause_ComputeWeight(CLAUSE, FLAGSTORE);
+NAT     clause_LiteralComputeWeight(LITERAL, FLAGSTORE);
+NAT     clause_ComputeTermDepth(CLAUSE);
+NAT     clause_MaxTermDepthClauseList(LIST);
+NAT     clause_ComputeSize(CLAUSE);
+BOOL    clause_WeightCorrect(CLAUSE, FLAGSTORE, PRECEDENCE);   /* Unused */
+
+LIST    clause_MoveBestLiteralToFront(LIST, SUBST, SYMBOL,
+				      BOOL (*)(LITERAL, NAT, LITERAL, NAT));
+
+
+LIST    clause_InsertWeighed(CLAUSE, LIST, FLAGSTORE, PRECEDENCE);
+LIST    clause_ListSortWeighed(LIST);
+
+BOOL    clause_HasTermSortConstraintLits(CLAUSE);
+BOOL    clause_HasSolvedConstraint(CLAUSE);
+BOOL    clause_IsDeclarationClause(CLAUSE);
+BOOL    clause_IsSortTheoryClause(CLAUSE, FLAGSTORE, PRECEDENCE);
+BOOL    clause_IsPartOfDefinition(CLAUSE, TERM, int*, LIST);
+BOOL    clause_IsPotentialSortTheoryClause(CLAUSE, FLAGSTORE, PRECEDENCE);
+BOOL    clause_HasOnlyVarsInConstraint(CLAUSE, FLAGSTORE, PRECEDENCE);
+BOOL    clause_HasSortInSuccedent(CLAUSE, FLAGSTORE, PRECEDENCE);
+BOOL    clause_ContainsPotPredDef(CLAUSE, FLAGSTORE, PRECEDENCE, NAT*, LIST*);
+BOOL    clause_LitsHaveCommonVar(LITERAL, LITERAL);
+
+void    clause_SelectLiteral(CLAUSE, FLAGSTORE);
+void    clause_SetSpecialFlags(CLAUSE,BOOL, FLAGSTORE, PRECEDENCE);
+
+BOOL    clause_LiteralIsLiteral(LITERAL);
+BOOL    clause_IsClause(CLAUSE, FLAGSTORE, PRECEDENCE);
+BOOL    clause_IsUnorderedClause(CLAUSE);
+BOOL    clause_ContainsPositiveEquations(CLAUSE);
+BOOL    clause_ContainsNegativeEquations(CLAUSE);
+int     clause_ContainsFolAtom(CLAUSE,BOOL*,BOOL*,BOOL*,BOOL*);
+BOOL    clause_ContainsVariables(CLAUSE);
+BOOL    clause_ContainsFunctions(CLAUSE);
+BOOL    clause_ContainsSymbol(CLAUSE, SYMBOL);
+void    clause_ContainsSortRestriction(CLAUSE,BOOL*,BOOL*);
+BOOL    clause_ImpliesFiniteDomain(CLAUSE);
+BOOL    clause_ImpliesNonTrivialDomain(CLAUSE);
+LIST    clause_FiniteMonadicPredicates(LIST);
+
+CLAUSE  clause_GetNumberedCl(int, LIST);
+LIST    clause_NumberSort(LIST);
+LIST    clause_NumberDelete(LIST,int);
+void    clause_Check(CLAUSE, FLAGSTORE, PRECEDENCE);
+
+void    clause_DeleteFlatFromIndex(CLAUSE, st_INDEX);
+void    clause_InsertFlatIntoIndex(CLAUSE, st_INDEX);
+void    clause_DeleteClauseListFlatFromIndex(LIST, st_INDEX);
+
+RULE    clause_GetOriginFromString(const char*);
+
+void    clause_CountSymbols(CLAUSE);
+
+LIST    clause_ListOfPredicates(CLAUSE);
+LIST    clause_ListOfConstants(CLAUSE);
+LIST    clause_ListOfVariables(CLAUSE);
+LIST    clause_ListOfFunctions(CLAUSE);
+
+/* special output functions for clauses with parent pointers */
+void clause_PParentsFPrint(FILE*, CLAUSE);
+void clause_PParentsListFPrint(FILE*, LIST L);
+void clause_PParentsPrint(CLAUSE);
+void clause_PParentsListPrint(LIST);
+void clause_PParentsFPrintGen(FILE*, CLAUSE, BOOL);
+
+
+/**************************************************************/
+/* Inline Functions                                           */
+/**************************************************************/
+
+/**************************************************************/
+/* Accessing Literals 1                                       */
+/**************************************************************/
+
+static __inline__ TERM clause_LiteralSignedAtom(LITERAL L)
+{
+  return L->atomWithSign;
+}
+
+
+static __inline__ CLAUSE clause_LiteralOwningClause(LITERAL L)
+{
+  return L->owningClause;
+}
+
+static __inline__ void clause_LiteralSetOwningClause(LITERAL L, CLAUSE C)
+{
+  L->owningClause = C;
+}
+
+
+static __inline__ void clause_LiteralSetOrientedEquality(LITERAL L)
+{
+  L->oriented = TRUE;
+}
+
+static __inline__ void clause_LiteralSetNoOrientedEquality(LITERAL L)
+{
+  L->oriented = FALSE;
+}
+
+
+static __inline__ NAT clause_LiteralWeight(LITERAL L)
+{
+#ifdef CHECK
+  if (L->weight == clause_WEIGHTUNDEFINED) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_LiteralWeight:");
+    misc_ErrorReport(" Tried to access undefined weight.");
+    misc_FinishErrorReport();
+  }
+#endif
+  return L->weight;
+}
+
+
+static __inline__ void clause_UpdateLiteralWeight(LITERAL L, FLAGSTORE Flags)
+{
+  L->weight = clause_LiteralComputeWeight(L, Flags);
+}
+
+
+static __inline__ void clause_LiteralFlagReset(LITERAL L)
+{
+  L->maxLit = 0;
+}
+
+static __inline__ BOOL clause_LiteralGetFlag(LITERAL L, MAXFLAG Flag)
+{
+  return ((L->maxLit & Flag) != 0);
+}
+
+static __inline__ void clause_LiteralSetFlag(LITERAL L, MAXFLAG Flag)
+{
+  L->maxLit = (L->maxLit) | Flag;
+}
+
+static __inline__ BOOL clause_LiteralIsMaximal(LITERAL L)
+{
+  return clause_LiteralGetFlag(L, MAXIMAL);
+}
+
+
+
+static __inline__ BOOL clause_LiteralIsOrientedEquality(LITERAL L)
+{
+  return L->oriented;
+}
+
+
+static __inline__ BOOL clause_LiteralIsNotOrientedEquality(LITERAL L)
+{
+  return !(L->oriented);
+}
+
+
+/**************************************************************/
+/* Literal Comparison 1                                       */
+/**************************************************************/
+
+static __inline__ BOOL clause_LiteralIsNegative(LITERAL L)
+{
+  return (term_TopSymbol(clause_LiteralSignedAtom(L)) == fol_Not());
+}
+
+static __inline__ BOOL clause_LiteralIsPositive(LITERAL L)
+{
+  return !clause_LiteralIsNegative(L);
+}
+
+
+static __inline__ BOOL clause_LiteralsAreComplementary(LITERAL L1, LITERAL L2)
+{
+  return ((clause_LiteralIsNegative(L1) &&
+	   clause_LiteralIsPositive(L2)) ||
+	  (clause_LiteralIsNegative(L2) &&
+	   clause_LiteralIsPositive(L1)));      /* xor */
+}
+
+static __inline__ BOOL clause_HyperLiteralIsBetter(LITERAL Dummy1, NAT S1,
+						   LITERAL Dummy2, NAT S2)
+/**************************************************************
+  INPUT:   Two literals and its sizes wrt. some substitution.
+  RETURNS: TRUE, if the first literal is 'better' than the second literal,
+           FALSE otherwise.
+  EFFECT:  A literal is 'better' than another, if S1 > Ss.
+           Since we have to find unifiable complementary literals
+	   for every remaining antecedent literal, it seems to be
+	   a good idea to try the most 'difficult' literal first,
+	   in order to stop the search as early as possible..
+	   Here we prefer the literal with the highest number
+	   of symbols..
+           This function is used as parameter for the function
+	   clause_MoveBestLiteralToFront.
+  CAUTION: The parameters <Dummy1> and <Dummy2> are unused, they're just
+           added to keep the compiler quiet.
+***************************************************************/
+{
+  return (S1 > S2);
+}
+
+
+/**************************************************************/
+/* Accessing Literals 2                                       */
+/**************************************************************/
+
+static __inline__ TERM clause_LiteralAtom(LITERAL L)
+{
+  if (clause_LiteralIsNegative(L))
+    return term_FirstArgument(clause_LiteralSignedAtom(L));
+  else
+    return clause_LiteralSignedAtom(L);
+}
+
+
+static __inline__ SYMBOL clause_LiteralPredicate(LITERAL L)
+{
+  return term_TopSymbol(clause_LiteralAtom(L));
+}
+
+static __inline__ BOOL clause_LiteralIsPredicate(LITERAL L)
+{
+  return !fol_IsEquality(clause_LiteralAtom(L));
+}
+
+static __inline__ BOOL clause_LiteralIsEquality(LITERAL L)
+{
+  return fol_IsEquality(clause_LiteralAtom(L));
+}
+
+static __inline__ BOOL clause_LiteralIsSort(LITERAL L)
+{
+  SYMBOL S;
+  S = clause_LiteralPredicate(L);
+  return (symbol_IsPredicate(S) &&
+	  (symbol_Arity(S) == 1));
+}
+
+
+static __inline__ void clause_LiteralSetAtom(LITERAL L, TERM A)
+{
+  if (clause_LiteralIsNegative(L))
+    list_Rplaca(term_ArgumentList(clause_LiteralSignedAtom(L)),A);
+  else
+    L->atomWithSign = A;
+}
+
+static __inline__ void clause_LiteralSetNegAtom(LITERAL L, TERM A)
+{
+  list_Rplaca(term_ArgumentList(clause_LiteralSignedAtom(L)), A);
+}
+
+static __inline__ void clause_LiteralSetPosAtom(LITERAL L, TERM A)
+{
+  L->atomWithSign = A;
+}
+
+static __inline__ void clause_NLiteralSetLiteral(LITERAL L, TERM LIT)
+{
+  L->atomWithSign = LIT;
+}
+
+/**************************************************************/
+/* Memory management                                          */
+/**************************************************************/
+
+static __inline__ void clause_LiteralFree(LITERAL L)
+{
+  memory_Free(L, sizeof(LITERAL_NODE));
+}
+
+
+/**************************************************************/
+/* Functions to access literals.                                 */
+/**************************************************************/
+
+static __inline__ LITERAL clause_GetLiteral(CLAUSE C, int Index)
+{
+  return C->literals[Index];
+}
+
+static __inline__ void clause_SetLiteral(CLAUSE C, int Index, LITERAL L)
+{
+  C->literals[Index]= L;
+}
+
+static __inline__ TERM clause_GetLiteralTerm(CLAUSE C, int Index)
+{
+  return clause_LiteralSignedAtom(clause_GetLiteral(C, Index));
+}
+
+static __inline__ TERM clause_GetLiteralAtom(CLAUSE C, int Index)
+{
+  return clause_LiteralAtom(clause_GetLiteral(C, Index));
+}
+
+static __inline__ int clause_NumOfConsLits(CLAUSE Clause)
+{
+  return Clause->c;
+}
+
+static __inline__ int clause_NumOfAnteLits(CLAUSE Clause)
+{
+  return Clause->a;
+}
+
+static __inline__ int clause_NumOfSuccLits(CLAUSE Clause)
+{
+  return Clause->s;
+}
+
+static __inline__ void clause_SetNumOfConsLits(CLAUSE Clause, int Number)
+{
+  Clause->c = Number;
+}
+
+static __inline__ void clause_SetNumOfAnteLits(CLAUSE Clause, int Number)
+{
+  Clause->a = Number;
+}
+
+static __inline__ void clause_SetNumOfSuccLits(CLAUSE Clause, int Number)
+{
+  Clause->s = Number;
+}
+
+static __inline__ int clause_Length(CLAUSE Clause)
+{
+  return (clause_NumOfConsLits(Clause) +
+	  clause_NumOfAnteLits(Clause) +
+	  clause_NumOfSuccLits(Clause));
+}
+
+
+static __inline__ int clause_LastLitIndex(CLAUSE Clause)
+{
+  return clause_Length(Clause) - 1;
+}
+
+static __inline__ int clause_FirstLitIndex(void)
+{
+  return 0;
+}
+
+static __inline__ int clause_FirstConstraintLitIndex(CLAUSE Clause)
+{
+  return 0;
+}
+
+static __inline__ int clause_FirstAntecedentLitIndex(CLAUSE Clause)
+{
+  return clause_NumOfConsLits(Clause);
+}
+
+static __inline__ int clause_FirstSuccedentLitIndex(CLAUSE Clause)
+{
+  return (clause_NumOfAnteLits(Clause) + clause_NumOfConsLits(Clause));
+}
+
+
+static __inline__ int clause_LastConstraintLitIndex(CLAUSE Clause)
+{
+  return clause_NumOfConsLits(Clause) - 1;
+}
+
+static __inline__ int clause_LastAntecedentLitIndex(CLAUSE Clause)
+{
+  return clause_FirstSuccedentLitIndex(Clause) - 1;
+}
+
+static __inline__ int clause_LastSuccedentLitIndex(CLAUSE Clause)
+{
+  return clause_Length(Clause) - 1;
+}
+
+static __inline__ LIST clause_GetLiteralList(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A clause.
+  RETURNS: A new list is created containing all literals of the
+           clause. The list contains pointers, not literal indexes.
+***************************************************************/
+{
+  LIST Result;
+  int  i;
+
+  Result = list_Nil();
+  for (i=clause_FirstLitIndex(); i<=clause_LastLitIndex(Clause); i++)
+    Result = list_Cons(clause_GetLiteral(Clause, i), Result);
+  return Result;
+}
+
+
+static __inline__ LIST clause_GetLiteralListExcept(CLAUSE Clause, int Index)
+/**************************************************************
+  INPUT:   A clause.
+  RETURNS: A new list is created containing all literals of the
+           clause except the literal at <Index>. The list contains
+	   pointers, not literal indexes.
+***************************************************************/
+{
+  LIST Result;
+  int  i;
+
+  Result = list_Nil();
+  for (i=clause_FirstLitIndex(); i<=clause_LastLitIndex(Clause); i++)
+    if (i != Index)
+      Result = list_Cons(clause_GetLiteral(Clause, i), Result);
+  return Result;
+}
+
+
+/**************************************************************/
+/* Clause Access Macros                                       */
+/**************************************************************/
+
+static __inline__ int clause_Counter(void)
+{
+  return clause_CLAUSECOUNTER;
+}
+
+static __inline__ void clause_SetCounter(int Value)
+{
+#ifdef CHECK
+  if (Value < 0) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_SetCounter: new counter value is negative.");
+    misc_FinishErrorReport();
+  }
+#endif
+  clause_CLAUSECOUNTER = Value;
+}
+
+static __inline__ int clause_IncreaseCounter(void)
+{
+#ifdef CHECK
+  if (clause_CLAUSECOUNTER == INT_MAX) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_IncreaseCounter: counter overflow.");
+    misc_FinishErrorReport();
+  }
+#endif
+  return clause_CLAUSECOUNTER++;
+}
+
+static __inline__ void clause_DecreaseCounter(void)
+{
+#ifdef CHECK
+  if (clause_CLAUSECOUNTER == 0) {
+    misc_FinishErrorReport();
+    misc_ErrorReport("\n In clause_DecreaseCounter: counter underflow.");
+    misc_FinishErrorReport();
+  }
+#endif
+  clause_CLAUSECOUNTER--;
+}
+
+static __inline__ NAT clause_Depth(CLAUSE Clause)
+{
+  return Clause->depth;
+}
+
+static __inline__ void clause_SetDepth(CLAUSE Clause, NAT NewDepth)
+{
+  Clause->depth = NewDepth;
+}
+
+
+static __inline__ NAT clause_Weight(CLAUSE Clause)
+{
+#ifdef CHECK
+  if (Clause->weight == clause_WEIGHTUNDEFINED) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_Weight: Tried to access undefined weight.");
+    misc_FinishErrorReport();
+  }
+#endif
+  return Clause->weight;
+}
+
+static __inline__ void clause_UpdateWeight(CLAUSE Clause, FLAGSTORE Flags)
+{
+  Clause->weight = clause_ComputeWeight(Clause, Flags);
+}
+
+
+static __inline__ int clause_Number(const CLAUSE Clause)
+{
+  return Clause->clausenumber;
+}
+
+static __inline__ void clause_SetNumber(CLAUSE Clause, int Number)
+{
+  Clause->clausenumber = Number;
+}
+
+static __inline__ void clause_NewNumber(CLAUSE Clause)
+{
+  Clause->clausenumber = clause_IncreaseCounter();
+}
+
+
+static __inline__ NAT clause_SplitLevel(CLAUSE Clause)
+{
+  return Clause->validlevel;
+}
+
+static __inline__ BOOL clause_CheckSplitLevel(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A clause.
+  RETURNS: TRUE, if the splitlevel invariant for the clause is fulfilled.
+  EFFECT:  Checks, if the validlevel of the clause is the order
+           of the highest set bit in the SPLITFIELD entry
+           of the clause.
+***************************************************************/
+{
+  if (Clause->validlevel == 0)
+    return (Clause->splitfield == NULL);
+  else {
+    int i, j;
+    for (i = Clause->splitfield_length-1; i >= 0; i--)
+      if (Clause->splitfield[i] != 0)
+	break;
+    for (j = sizeof(SPLITFIELDENTRY)*CHAR_BIT-1; j >= 0; j--)
+      if (Clause->splitfield[i] & ((SPLITFIELDENTRY)1 << j))
+	break;
+    return (Clause->validlevel == (i*sizeof(SPLITFIELDENTRY)*CHAR_BIT+j));
+  }
+}
+
+static __inline__ LIST clause_ParentClauses(CLAUSE Clause)
+{
+  return Clause->parentCls;
+}
+
+static __inline__ LIST clause_ParentLiterals(CLAUSE Clause)
+{
+  return Clause->parentLits;
+}
+
+
+static __inline__ SYMBOL clause_MaxVar(CLAUSE Clause)
+{
+  return Clause->maxVar;
+}
+
+static __inline__ void clause_SetMaxVar(CLAUSE Clause, SYMBOL Variable)
+{
+  Clause->maxVar = Variable;
+}
+
+
+static __inline__ RULE clause_Origin(CLAUSE Clause)
+{
+  return Clause->origin;
+}
+
+static __inline__ BOOL clause_Exists(CLAUSE Clause)
+{
+  return (Clause != (CLAUSE)NULL);
+}
+
+static __inline__ BOOL clause_LiteralExists(LITERAL L)
+{
+  return (L != (LITERAL)NULL);
+}
+
+static __inline__ CLAUSE clause_Null(void)
+{
+  return (CLAUSE) NULL;
+}
+
+static __inline__ void clause_SetSplitLevel(CLAUSE Clause, NAT Level)
+{
+  Clause->validlevel = Level;
+}
+
+static __inline__ void clause_InitSplitData(CLAUSE C)
+{
+  C->splitfield = NULL;
+  C->splitfield_length = 0;
+  clause_SetSplitLevel(C, 0);
+}
+
+static __inline__ void clause_SetSplitField(CLAUSE Clause, SPLITFIELD B,
+					    unsigned Length)
+{
+  unsigned i;
+  if (Clause->splitfield_length != Length) {
+    if (Clause->splitfield != NULL) {
+      memory_Free(Clause->splitfield,
+		  sizeof(SPLITFIELDENTRY) * Clause->splitfield_length);
+    }
+    if (Length != 0) {
+      Clause->splitfield = memory_Malloc(sizeof(SPLITFIELDENTRY) * Length);
+    }
+    else
+      Clause->splitfield = NULL;
+    Clause->splitfield_length = Length;
+  }
+  for (i=0; i < Length; i++)
+    Clause->splitfield[i] = B[i];
+}
+
+
+static __inline__ NAT  clause_ComputeSplitFieldAddress(NAT n, NAT* field)
+{
+  *field = 0;
+  while (n >= (sizeof(SPLITFIELDENTRY) * CHAR_BIT)) {
+    (*field)++;
+    n -= sizeof(SPLITFIELDENTRY) * CHAR_BIT;
+  }
+  return n;
+}
+
+static __inline__ void clause_ExpandSplitField(CLAUSE C, NAT Length)
+{
+  SPLITFIELD NewField;
+  NAT i;
+  if (C->splitfield_length < Length) {
+    NewField = memory_Malloc(sizeof(SPLITFIELDENTRY) * Length);
+    for (i=0; i < C->splitfield_length; i++)
+      NewField[i] = C->splitfield[i];
+    for (i=C->splitfield_length; i < Length; i++)
+      NewField[i] = 0;
+    if (C->splitfield != NULL) {
+      memory_Free(C->splitfield,
+		  sizeof(SPLITFIELDENTRY) * C->splitfield_length);
+    }
+    C->splitfield = NewField;
+    C->splitfield_length = Length;
+  }
+}
+
+static __inline__ void clause_UpdateSplitField(CLAUSE C1, CLAUSE C2)
+  /* Add the split data of <C2> to <C1> */
+{
+  unsigned i;
+  if (C1->splitfield_length < C2->splitfield_length)
+    clause_ExpandSplitField(C1, C2->splitfield_length);
+  for (i=0; i < C2->splitfield_length; i++)
+    C1->splitfield[i] = C1->splitfield[i] | C2->splitfield[i];
+}
+
+static __inline__ void clause_ClearSplitField(CLAUSE C)
+{
+  int i;
+
+  for (i=C->splitfield_length-1; i >=0; i--)
+    C->splitfield[i] = 0;
+}
+	
+static __inline__ void clause_SetSplitFieldBit(CLAUSE Clause, NAT n)
+{
+  unsigned field;
+  
+  n = clause_ComputeSplitFieldAddress(n, &field);
+  if (field >= Clause->splitfield_length)
+    clause_ExpandSplitField(Clause, field + 1);
+  Clause->splitfield[field] = (Clause->splitfield[field]) |
+    ((SPLITFIELDENTRY)1 << n);
+}
+
+static __inline__ BOOL clause_GetFlag(CLAUSE Clause, CLAUSE_FLAGS Flag)
+{
+  return (Clause->flags & Flag) != 0;
+}
+
+static __inline__ void clause_SetFlag(CLAUSE Clause, CLAUSE_FLAGS Flag)
+{
+  Clause->flags = Clause->flags | Flag;
+}
+
+static __inline__ void clause_RemoveFlag(CLAUSE Clause, CLAUSE_FLAGS Flag)
+{
+  if (Clause->flags & Flag)
+    Clause->flags = Clause->flags - Flag;
+}
+
+static __inline__ void clause_ClearFlags(CLAUSE Clause)
+{
+  Clause->flags = 0;
+}
+
+
+static __inline__ BOOL clause_DependsOnSplitLevel(CLAUSE C, NAT N)
+{
+  if (N==0)
+    return TRUE;
+  else {
+    unsigned field;
+    N = clause_ComputeSplitFieldAddress(N, &field);
+    if (field >= C->splitfield_length)
+      return FALSE;
+    else
+      return (C->splitfield[field] & ((SPLITFIELDENTRY)1 << N)) != 0;
+  }
+}
+
+static __inline__ void clause_SetSplitDataFromFather(CLAUSE Result,
+						     CLAUSE Father)
+{
+  if (clause_GetFlag(Father, CONCLAUSE))
+    clause_SetFlag(Result, CONCLAUSE);
+  clause_SetSplitLevel(Result, clause_SplitLevel(Father));
+  clause_SetSplitField(Result, Father->splitfield, Father->splitfield_length);
+}
+
+static __inline__ void clause_UpdateSplitDataFromNewSplitting(CLAUSE Result,
+							      CLAUSE Father,
+							      NAT Level)
+{
+  unsigned field;
+  NAT i;
+  
+  clause_SetSplitLevel(Result, Level);
+  Level = clause_ComputeSplitFieldAddress(Level, &field);
+
+  if (field >= Result->splitfield_length) {
+    if (Result->splitfield != NULL)
+      memory_Free(Result->splitfield,
+		  sizeof(SPLITFIELDENTRY) * Result->splitfield_length);
+    Result->splitfield = memory_Malloc((field + 1) * sizeof(SPLITFIELDENTRY));
+    Result->splitfield_length = field + 1;
+  }
+  if (clause_GetFlag(Father, CONCLAUSE))
+    clause_SetFlag(Result, CONCLAUSE);
+  for (i=0; i < Father->splitfield_length; i++)
+    Result->splitfield[i] = Father->splitfield[i];
+  for (i=Father->splitfield_length; i < Result->splitfield_length; i++)
+    Result->splitfield[i] = 0;
+  Result->splitfield[field] = (Result->splitfield[field] | ((SPLITFIELDENTRY)1 << Level));
+}
+
+static __inline__ void clause_UpdateSplitDataFromPartner(CLAUSE Result,
+							 CLAUSE Partner)
+{
+  if (clause_GetFlag(Partner, CONCLAUSE))
+    clause_SetFlag(Result, CONCLAUSE);
+  if (clause_SplitLevel(Partner) == 0)
+    return;
+  /* Set Split level to misc_Max(Partner, Result) */
+  clause_SetSplitLevel(Result, clause_SplitLevel(Partner) > clause_SplitLevel(Result)
+		       ? clause_SplitLevel(Partner)
+		       : clause_SplitLevel(Result));
+  clause_UpdateSplitField(Result, Partner);
+}
+
+static __inline__ void clause_SetSplitDataFromList(CLAUSE Result, LIST List)
+{
+  CLAUSE TempClause;
+  LIST Scan;
+  NAT  l;
+  Scan = List;
+  l = Result->splitfield_length;
+  while (!list_Empty(Scan)) {
+    TempClause = (CLAUSE) list_Top(Scan);
+    if (clause_GetFlag(TempClause, CONCLAUSE))
+      clause_SetFlag(Result, CONCLAUSE);
+    clause_SetSplitLevel(Result,
+			 clause_SplitLevel(TempClause) > clause_SplitLevel(Result)
+			 ? clause_SplitLevel(TempClause)
+			 : clause_SplitLevel(Result));
+    if (l < TempClause->splitfield_length)
+      l = TempClause->splitfield_length;
+    Scan = list_Cdr(Scan);
+  }
+  if (l > Result->splitfield_length) {
+    if (Result->splitfield != NULL)
+      memory_Free(Result->splitfield,
+		  sizeof(SPLITFIELDENTRY) * Result->splitfield_length);
+    Result->splitfield = memory_Malloc(sizeof(SPLITFIELDENTRY) * l);
+    Result->splitfield_length = l;
+  }
+  
+  for (l=0; l < Result->splitfield_length; l++)
+    Result->splitfield[l] = 0;
+  
+  while (!list_Empty(List)) {
+    TempClause= (CLAUSE) list_Top(List);
+    List = list_Cdr(List);
+    for (l=0; l < TempClause->splitfield_length; l++)
+      Result->splitfield[l] = Result->splitfield[l] | TempClause->splitfield[l];
+  }
+}
+
+
+static __inline__ void clause_SetSplitDataFromParents(CLAUSE Result,
+						      CLAUSE Mother,
+						      CLAUSE Father)
+{
+  NAT i;
+  if (clause_GetFlag(Father, CONCLAUSE) || clause_GetFlag(Mother, CONCLAUSE))
+    clause_SetFlag(Result, CONCLAUSE);
+  if ((clause_SplitLevel(Father) == 0) && (clause_SplitLevel(Mother) == 0))
+    return;
+  clause_SetSplitLevel(Result, clause_SplitLevel(Mother) > clause_SplitLevel(Father)
+		       ? clause_SplitLevel(Mother)
+		       : clause_SplitLevel(Father));
+  
+  if (Mother->splitfield_length > Father->splitfield_length) {
+    if (Result->splitfield != NULL)
+      memory_Free(Result->splitfield,
+		  sizeof(SPLITFIELDENTRY) * Result->splitfield_length);
+    Result->splitfield = memory_Malloc(sizeof(SPLITFIELDENTRY) *
+				       Mother->splitfield_length);
+    Result->splitfield_length = Mother->splitfield_length;
+    for (i=0; i < Father->splitfield_length; i++)
+      Result->splitfield[i] =
+	Mother->splitfield[i] | Father->splitfield[i];
+    for (i=Father->splitfield_length; i < Mother->splitfield_length; i++)
+      Result->splitfield[i] = Mother->splitfield[i];
+  }
+  else {
+    if (Result->splitfield != NULL)
+      memory_Free(Result->splitfield,
+		  sizeof(SPLITFIELDENTRY) * Result->splitfield_length);
+    Result->splitfield = memory_Malloc(sizeof(SPLITFIELDENTRY) *
+				       Father->splitfield_length);
+    Result->splitfield_length = Father->splitfield_length;
+    for (i=0; i < Mother->splitfield_length; i++)
+      Result->splitfield[i] =
+	Mother->splitfield[i] | Father->splitfield[i];
+    for (i=Mother->splitfield_length; i < Father->splitfield_length; i++)
+      Result->splitfield[i] = Father->splitfield[i];
+  }
+}
+
+static __inline__ void clause_SetParentClauses(CLAUSE Clause, LIST PClauses)
+{
+  Clause->parentCls = PClauses;
+}
+
+static __inline__ void clause_AddParentClause(CLAUSE Clause, int PClause)
+{
+  Clause->parentCls = list_Cons((POINTER) PClause, Clause->parentCls);
+}
+
+static __inline__ void clause_SetParentLiterals(CLAUSE Clause, LIST PLits)
+{
+  Clause->parentLits = PLits;
+}
+
+static __inline__ void clause_AddParentLiteral(CLAUSE Clause, int PLit)
+{
+  Clause->parentLits = list_Cons((POINTER) PLit, Clause->parentLits);
+}
+
+
+static __inline__ BOOL clause_ValidityIsNotSmaller(CLAUSE C1, CLAUSE C2)
+{
+  return (C1->validlevel <= C2->validlevel);
+}
+
+static __inline__ BOOL clause_IsMoreValid(CLAUSE C1, CLAUSE C2)
+{
+  return (C1->validlevel < C2->validlevel);
+}
+
+
+static __inline__ BOOL  clause_CompareAbstractLEQ (CLAUSE Left, CLAUSE Right) 
+/**************************************************************
+  INPUT:   Two clauses.
+  RETURNS: TRUE if left <= right, FALSE otherwise.
+  EFFECTS: Internal function used to compare clauses for
+           sorting.
+  CAUTION: Expects clause literal order to be fixed.
+***************************************************************/
+{
+  return (BOOL) (clause_CompareAbstract(Left, Right) <= 0);
+}
+
+
+static __inline__ BOOL clause_IsFromRewriting(CLAUSE Clause)
+{
+  return Clause->origin == REWRITING;
+}
+
+static __inline__ BOOL clause_IsFromCondensing(CLAUSE Clause)
+{
+  return Clause->origin == CONDENSING;
+}
+
+static __inline__ BOOL clause_IsFromObviousReductions(CLAUSE Clause)
+{
+  return Clause->origin == OBVIOUS_REDUCTIONS;
+}
+
+static __inline__ BOOL clause_IsFromSortSimplification(CLAUSE Clause)
+{
+  return Clause->origin == SORT_SIMPLIFICATION;
+}
+
+static __inline__ BOOL clause_IsFromMatchingReplacementResolution(CLAUSE Clause)
+{
+  return Clause->origin == MATCHING_REPLACEMENT_RESOLUTION;
+}
+
+static __inline__  BOOL clause_IsFromClauseDeletion(CLAUSE Clause)
+{
+  return Clause->origin == CLAUSE_DELETION;
+}
+
+static __inline__ BOOL clause_IsFromEmptySort(CLAUSE Clause)
+{
+  return Clause->origin == EMPTY_SORT;
+}
+
+static __inline__ BOOL clause_IsFromSortResolution(CLAUSE Clause)
+{
+  return Clause->origin == SORT_RESOLUTION;
+}
+
+static __inline__ BOOL clause_IsFromUnitConflict(CLAUSE Clause)
+{
+  return Clause->origin == UNIT_CONFLICT;
+}
+
+static __inline__ BOOL clause_IsFromEqualityResolution(CLAUSE Clause)
+{
+  return Clause->origin == EQUALITY_RESOLUTION;
+}
+
+static __inline__ BOOL clause_IsFromEqualityFactoring(CLAUSE Clause)
+{
+  return Clause->origin == EQUALITY_FACTORING;
+}
+
+static __inline__ BOOL clause_IsFromMergingParamodulation(CLAUSE Clause)
+{
+  return Clause->origin == MERGING_PARAMODULATION;
+}
+
+static __inline__ BOOL clause_IsFromSuperpositionRight(CLAUSE Clause)
+{
+  return Clause->origin == SUPERPOSITION_RIGHT;
+}
+
+static __inline__ BOOL clause_IsFromSuperpositionLeft(CLAUSE Clause)
+{
+  return Clause->origin == SUPERPOSITION_LEFT;
+}
+
+static __inline__ BOOL clause_IsFromGeneralResolution(CLAUSE Clause)
+{
+  return Clause->origin == GENERAL_RESOLUTION;
+}
+
+static __inline__ BOOL clause_IsFromGeneralFactoring(CLAUSE Clause)
+{
+  return Clause->origin == GENERAL_FACTORING;
+}
+
+static __inline__ BOOL clause_IsFromSplitting(CLAUSE Clause)
+{
+  return Clause->origin == SPLITTING;
+}
+
+static __inline__ BOOL clause_IsFromDefApplication(CLAUSE Clause)
+{
+  return Clause->origin == DEFAPPLICATION;
+}
+
+static __inline__ BOOL clause_IsFromTerminator(CLAUSE Clause)
+{
+  return Clause->origin == TERMINATOR;
+}
+
+static __inline__ BOOL clause_IsTemporary(CLAUSE Clause)
+{
+  return Clause->origin == TEMPORARY;
+}
+
+static __inline__ BOOL clause_IsFromInput(CLAUSE Clause)
+{
+  return Clause->origin == INPUT;
+}
+
+
+static __inline__ BOOL clause_HasReducedPredecessor(CLAUSE Clause)
+{
+  RULE origin = clause_Origin(Clause);
+
+  return (origin == CONDENSING                   ||
+	  origin == REWRITING                    ||
+	  origin == SPLITTING                    ||
+	  origin == ASSIGNMENT_EQUATION_DELETION ||
+	  origin == SORT_SIMPLIFICATION          ||
+	  origin == OBVIOUS_REDUCTIONS);
+}
+
+static __inline__ BOOL clause_IsSplitFather(CLAUSE C1, CLAUSE C2)
+{
+  return (C1->clausenumber == (int)list_Car(C2->parentCls));
+}
+
+
+static __inline__ void clause_SetFromRewriting(CLAUSE Clause)
+{
+  Clause->origin = REWRITING;
+}
+
+static __inline__ void clause_SetFromContextualRewriting(CLAUSE Clause)
+{
+  Clause->origin = CONTEXTUAL_REWRITING;
+}
+
+static __inline__ void clause_SetFromUnitConflict(CLAUSE Clause)
+{
+  Clause->origin = UNIT_CONFLICT;
+}
+
+static __inline__ void clause_SetFromCondensing(CLAUSE Clause)
+{
+  Clause->origin = CONDENSING;
+}
+
+static __inline__ void clause_SetFromAssignmentEquationDeletion(CLAUSE Clause)
+{
+  Clause->origin = ASSIGNMENT_EQUATION_DELETION;
+}
+
+static __inline__ void clause_SetFromObviousReductions(CLAUSE Clause)
+{
+  Clause->origin = OBVIOUS_REDUCTIONS;
+}
+
+static __inline__ void clause_SetFromSortSimplification(CLAUSE Clause)
+{
+  Clause->origin = SORT_SIMPLIFICATION;
+}
+
+static __inline__ void clause_SetFromMatchingReplacementResolution(CLAUSE Clause)
+{
+  Clause->origin = MATCHING_REPLACEMENT_RESOLUTION;
+}
+
+static __inline__ void clause_SetFromClauseDeletion(CLAUSE Clause)
+{
+  Clause->origin = CLAUSE_DELETION;
+}
+
+static __inline__ void clause_SetFromEmptySort(CLAUSE Clause)
+{
+  Clause->origin = EMPTY_SORT;
+}
+
+static __inline__ void clause_SetFromSortResolution(CLAUSE Clause)
+{
+  Clause->origin = SORT_RESOLUTION;
+}
+
+static __inline__ void clause_SetFromEqualityResolution(CLAUSE Clause)
+{
+  Clause->origin = EQUALITY_RESOLUTION;
+}
+
+static __inline__ void clause_SetFromEqualityFactoring(CLAUSE Clause)
+{
+  Clause->origin = EQUALITY_FACTORING;
+}
+
+static __inline__ void clause_SetFromMergingParamodulation(CLAUSE Clause)
+{
+  Clause->origin = MERGING_PARAMODULATION;
+}
+
+static __inline__ void clause_SetFromParamodulation(CLAUSE Clause)
+{
+  Clause->origin = PARAMODULATION;
+}
+static __inline__ void clause_SetFromOrderedParamodulation(CLAUSE Clause)
+{
+  Clause->origin = ORDERED_PARAMODULATION;
+}
+static __inline__ void clause_SetFromSuperpositionRight(CLAUSE Clause)
+{
+  Clause->origin = SUPERPOSITION_RIGHT;
+}
+
+static __inline__ void clause_SetFromSuperpositionLeft(CLAUSE Clause)
+{
+  Clause->origin = SUPERPOSITION_LEFT;
+}
+
+static __inline__ void clause_SetFromGeneralResolution(CLAUSE Clause)
+{
+  Clause->origin = GENERAL_RESOLUTION;
+}
+
+static __inline__ void clause_SetFromOrderedHyperResolution(CLAUSE Clause)
+{
+  Clause->origin = ORDERED_HYPER;
+}
+
+static __inline__ void clause_SetFromSimpleHyperResolution(CLAUSE Clause)
+{
+  Clause->origin = SIMPLE_HYPER;
+}
+
+static __inline__ void clause_SetFromURResolution(CLAUSE Clause)
+{
+  Clause->origin = UR_RESOLUTION;
+}
+
+static __inline__ void clause_SetFromGeneralFactoring(CLAUSE Clause)
+{
+  Clause->origin = GENERAL_FACTORING;
+}
+
+static __inline__ void clause_SetFromSplitting(CLAUSE Clause)
+{
+  Clause->origin = SPLITTING;
+}
+
+static __inline__ void clause_SetFromDefApplication(CLAUSE Clause)
+{
+  Clause->origin = DEFAPPLICATION;
+}
+
+static __inline__ void clause_SetFromTerminator(CLAUSE Clause)
+{
+  Clause->origin = TERMINATOR;
+}
+
+static __inline__ void clause_SetTemporary(CLAUSE Clause)
+{
+  Clause->origin = TEMPORARY;
+}
+
+
+static __inline__ void clause_SetFromInput(CLAUSE Clause)
+{
+  Clause->origin = INPUT;
+}
+
+
+static __inline__ LITERAL clause_FirstConstraintLit(CLAUSE Clause)
+{
+  return Clause->literals[0];
+}
+
+static __inline__ LITERAL clause_FirstAntecedentLit(CLAUSE Clause)
+{
+  return Clause->literals[clause_FirstAntecedentLitIndex(Clause)];
+}
+
+static __inline__ LITERAL clause_FirstSuccedentLit(CLAUSE Clause)
+{
+  return Clause->literals[clause_FirstSuccedentLitIndex(Clause)];
+}
+
+static __inline__ LITERAL clause_LastConstraintLit(CLAUSE Clause)
+{
+  return Clause->literals[clause_LastConstraintLitIndex(Clause)];
+}
+
+static __inline__ LITERAL clause_LastAntecedentLit(CLAUSE Clause)
+{
+  return Clause->literals[clause_LastAntecedentLitIndex(Clause)];
+}
+
+static __inline__ LITERAL clause_LastSuccedentLit(CLAUSE Clause)
+{
+  return Clause->literals[clause_LastSuccedentLitIndex(Clause)];
+}
+
+
+static __inline__ BOOL clause_HasEmptyConstraint(CLAUSE Clause)
+{
+  return clause_NumOfConsLits(Clause) == 0;
+}
+
+static __inline__ BOOL clause_HasEmptyAntecedent(CLAUSE Clause)
+{
+  return clause_NumOfAnteLits(Clause) == 0;
+}
+
+static __inline__ BOOL clause_HasEmptySuccedent(CLAUSE Clause)
+{
+  return clause_NumOfSuccLits(Clause) == 0;
+}
+
+
+static __inline__ BOOL clause_IsGround(CLAUSE Clause)
+{
+#ifdef CHECK
+  if (!symbol_Equal(clause_MaxVar(Clause), clause_SearchMaxVar(Clause))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In clause_IsGround: Clause is corrupted.");
+    misc_FinishErrorReport();
+  }
+#endif
+  return (symbol_VarIndex(clause_MaxVar(Clause)) ==
+	  symbol_GetInitialStandardVarCounter());
+}
+
+static __inline__ BOOL clause_IsEmptyClause(CLAUSE C)
+{
+  return (C != (CLAUSE)NULL &&
+	  clause_HasEmptyAntecedent(C) &&
+	  clause_HasEmptySuccedent(C)  &&
+	  clause_HasEmptyConstraint(C));
+}
+
+static __inline__ int clause_LiteralGetIndex(LITERAL L)
+{
+  int j = 0;
+
+  while (clause_GetLiteral(clause_LiteralOwningClause(L), j) != L)
+    j++;
+
+  return j;
+}
+
+static __inline__ BOOL clause_LiteralIsFromConstraint(LITERAL Literal)
+{
+  int    index  = clause_LiteralGetIndex(Literal);
+  CLAUSE clause = clause_LiteralOwningClause(Literal);
+
+  return (index <= clause_LastConstraintLitIndex(clause) &&
+	  index >= clause_FirstConstraintLitIndex(clause));
+}
+
+static __inline__ BOOL clause_LiteralIsFromAntecedent(LITERAL Literal)
+{
+  int    index  = clause_LiteralGetIndex(Literal);
+  CLAUSE clause = clause_LiteralOwningClause(Literal);
+
+  return (index <= clause_LastAntecedentLitIndex(clause) &&
+	  index >= clause_FirstAntecedentLitIndex(clause));
+}
+
+static __inline__ BOOL clause_LiteralIsFromSuccedent(LITERAL Literal)
+{
+   int    index;
+   CLAUSE clause;
+   index  = clause_LiteralGetIndex(Literal);
+   clause = clause_LiteralOwningClause(Literal);
+   return (index <= clause_LastSuccedentLitIndex(clause) &&
+	   index >= clause_FirstSuccedentLitIndex(clause));
+}
+
+static __inline__ BOOL clause_IsSimpleSortClause(CLAUSE Clause)
+{
+  return (clause_HasEmptyAntecedent(Clause) &&
+	  (clause_NumOfSuccLits(Clause) == 1) &&
+	  clause_LiteralIsSort(clause_GetLiteral(Clause,
+				clause_NumOfConsLits(Clause))) &&
+	  clause_HasSolvedConstraint(Clause));
+}
+
+static __inline__ BOOL clause_IsSubsortClause(CLAUSE Clause)
+{
+  return (clause_IsSimpleSortClause(Clause) &&
+	  term_IsVariable(term_FirstArgument(
+            clause_LiteralSignedAtom(
+	      clause_GetLiteral(Clause, clause_NumOfConsLits(Clause))))));
+}
+
+
+static __inline__ BOOL clause_HasSuccLits(CLAUSE Clause)
+{
+  return (clause_NumOfSuccLits(Clause) > 1);
+}
+
+static __inline__ BOOL clause_HasGroundSuccLit(CLAUSE Clause)
+{
+  int  i, l;
+
+  l = clause_Length(Clause);
+  for (i = clause_FirstSuccedentLitIndex(Clause); i < l; i++)
+    if (term_IsGround(Clause->literals[i]->atomWithSign))
+      return TRUE;
+  
+  return FALSE;
+}
+
+static __inline__ LITERAL clause_GetGroundSuccLit(CLAUSE Clause)
+{
+  int  i, l;
+
+  l = clause_Length(Clause);
+  for (i = clause_FirstSuccedentLitIndex(Clause); i < l; i++)
+    if (term_IsGround(Clause->literals[i]->atomWithSign))
+      return Clause->literals[i];
+
+  return (LITERAL)NULL;
+}
+
+
+static __inline__ void clause_Free(CLAUSE Clause)
+{
+  memory_Free(Clause, sizeof(CLAUSE_NODE));
+}
+
+
+static __inline__ void clause_ReInit(CLAUSE Clause,
+				     FLAGSTORE Flags,
+				     PRECEDENCE Precedence)
+{
+  clause_Normalize(Clause);
+  clause_SetMaxLitFlags(Clause, Flags, Precedence);
+  clause_UpdateWeight(Clause, Flags);
+  clause_UpdateMaxVar(Clause);
+}
+
+static __inline__ void clause_OrientAndReInit(CLAUSE Clause, FLAGSTORE Flags,
+					      PRECEDENCE Precedence)
+{
+  clause_OrientEqualities(Clause, Flags, Precedence);
+  clause_ReInit(Clause, Flags, Precedence);
+}
+
+static __inline__ void clause_SetDataFromFather(CLAUSE Result, CLAUSE Father,
+						int i, FLAGSTORE Flags,
+						PRECEDENCE Precedence)
+{
+  clause_OrientAndReInit(Result, Flags, Precedence);
+  clause_SetSplitDataFromFather(Result, Father);
+  clause_SetDepth(Result, clause_Depth(Father) + 1);
+  clause_AddParentClause(Result, clause_Number(Father));
+  clause_AddParentLiteral(Result, i);
+}
+
+
+static __inline__ void clause_SetDataFromParents(CLAUSE Result, CLAUSE Father,
+						 int i, CLAUSE Mother, int j,
+						 FLAGSTORE Flags,
+						 PRECEDENCE Precedence)
+{
+  clause_OrientAndReInit(Result, Flags, Precedence);
+  clause_SetSplitDataFromParents(Result, Father, Mother);
+  clause_SetDepth(Result,
+		  misc_Max(clause_Depth(Father), clause_Depth(Mother)) +1);
+  clause_AddParentClause(Result, clause_Number(Father));
+  clause_AddParentLiteral(Result, i);
+  clause_AddParentClause(Result, clause_Number(Mother));
+  clause_AddParentLiteral(Result, j);
+}
+
+
+#endif
+
diff --git a/test/spass/clock.c b/test/spass/clock.c
new file mode 100644
index 0000000000000000000000000000000000000000..7106669ae44cd7fa7f4a88c48313231d54c4eef0
--- /dev/null
+++ b/test/spass/clock.c
@@ -0,0 +1,215 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                     CLOCK                              * */
+/* *                                                        * */
+/* *  $Module:   CLOCK                                      * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1999, 2000, 2001                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "clock.h"
+
+
+/**************************************************************/
+/* Global Variables                                           */
+/**************************************************************/
+
+float      clock_Akku[clock_TYPESIZE];
+CLOCK_TMS  clock_Counters[clock_TYPESIZE];
+
+#ifdef WIN
+float      clock_Ping;
+#endif
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+void clock_Init(void)
+/*********************************************************
+  INPUT:   None.
+  EFFECT:  Initializes the clock Module.
+  RETURNS: None.
+  MEMORY:  None.
+**********************************************************/
+{
+  int i;
+
+  for (i=0;i<clock_TYPESIZE;i++) {
+    clock_InitCounter(i);
+  }
+#ifdef WIN
+  clock_Ping = 0;
+#endif
+}
+
+
+
+void clock_InitCounter(CLOCK_CLOCKS ClockCounter)
+/*********************************************************
+  INPUT:   A clock counter.
+  EFFECT:  The clock counter <ClockCounter> is initialized.
+  RETURNS: None.
+  MEMORY:  None.
+**********************************************************/
+{
+  clock_Akku[ClockCounter] = 0;
+}
+
+
+void clock_StartCounter(CLOCK_CLOCKS ClockCounter)
+/*********************************************************
+  INPUT:   A clock counter.
+  EFFECT:  The clock counter <ClockCounter> is started.
+  RETURNS: None.
+  MEMORY:  None.
+**********************************************************/
+{
+#ifndef CLOCK_NO_TIMING
+  ftime(&(clock_Counters[ClockCounter]));
+#endif
+}
+
+
+void clock_StopPassedTime(CLOCK_CLOCKS ClockCounter) 
+/*********************************************************
+  INPUT:   A clock counter.
+  EFFECT:  Stores the number of seconds passed since given
+           counter was started in the according
+	   accumulator.
+  RETURNS: None.
+  MEMORY:  None.
+**********************************************************/
+{
+#ifndef CLOCK_NO_TIMING
+  CLOCK_TMS    newtime;
+  ftime(&newtime);
+  clock_Akku[ClockCounter] = clock_GetSeconds(ClockCounter);
+#endif
+}
+
+
+void clock_StopAddPassedTime(CLOCK_CLOCKS ClockCounter) 
+/*********************************************************
+  INPUT:   A clock counter.
+  EFFECT:  Adds the number of seconds passed since given
+           counter was started to the according
+	   accumulator.
+  RETURNS: None.
+  MEMORY:  None.
+**********************************************************/
+{
+#ifndef CLOCK_NO_TIMING
+  CLOCK_TMS    newtime;
+  ftime(&newtime);
+  clock_Akku[ClockCounter] += clock_GetSeconds(ClockCounter);
+#endif
+}
+
+
+float clock_GetSeconds(CLOCK_CLOCKS ClockCounter)
+/*********************************************************
+  INPUT:   A clock counter.
+  EFFECT:  Computes the number of seconds spent by the
+           counter.
+  RETURNS: The number of seconds spent by the counter as
+           a float.
+  MEMORY:  None.
+**********************************************************/
+{
+#ifndef CLOCK_NO_TIMING
+  CLOCK_TMS    newtime;
+  ftime(&newtime);
+  return ((float) (newtime.time - clock_Counters[ClockCounter].time)
+	  + (((newtime.millitm - clock_Counters[ClockCounter].millitm))
+	     /(float)1000));
+#else
+  return 0;
+#endif
+}
+
+#ifdef WIN
+void clock_PingOneSecond(void)
+/*********************************************************
+  INPUT:   None but assumes the clock_OVERALL to be properly
+           initialized.
+  EFFECT:  If between the previous call to this function or
+           to clock_Init more one second is passed, the
+	   function prints a "PING" to stdout.
+	   Needed only for the windows implementation.
+  CAUTION: Only needed to get around Windows95/98 scheduling
+           problems.
+**********************************************************/
+{
+  if (clock_GetSeconds(clock_OVERALL) > clock_Ping + 1) {
+    clock_Ping++;
+    puts("\n PING ");
+  }
+}
+#endif
+
+
+
+void clock_PrintTime(CLOCK_CLOCKS ClockCounter)
+/*********************************************************
+  INPUT:   A clock counter.
+  EFFECT:  The time is printed in format hh:mm:ss.dd to stdout
+  RETURNS: None.
+  MEMORY:  None.
+**********************************************************/
+{
+#ifndef CLOCK_NO_TIMING
+  NAT   hours, minutes;
+  float seconds;
+
+  seconds   = clock_Akku[ClockCounter];
+  hours     = (NAT)seconds/3600;
+  seconds  -= hours*3600;
+  minutes   = (NAT)seconds/60;
+  seconds  -= (minutes*60);
+  if (seconds >= 10.0)
+    printf("%u:%02u:%2.2f",hours,minutes,seconds);
+  else
+    printf("%u:%02u:0%2.2f",hours,minutes,seconds);
+#else
+  fputs(" No Timing on this machine. ",stdout);
+#endif
+}
diff --git a/test/spass/clock.h b/test/spass/clock.h
new file mode 100644
index 0000000000000000000000000000000000000000..6e6757426944f2e4bedee4fb832bb4b4f21dda72
--- /dev/null
+++ b/test/spass/clock.h
@@ -0,0 +1,78 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                     CLOCK                              * */
+/* *                                                        * */
+/* *  $Module:   CLOCK                                      * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1999, 2001                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* $RCSfile$ */
+
+#ifndef _CLOCK_
+#define _CLOCK_
+
+#include "misc.h"
+#include <sys/types.h>
+#include <sys/timeb.h>
+
+typedef enum {
+  clock_BACKTRACK,
+  clock_OVERALL,
+  clock_INPUT,
+  clock_CNF,
+  clock_REDUCTION,
+  clock_INFERENCE,
+  clock_TYPESIZE
+} CLOCK_CLOCKS;
+
+typedef struct timeb CLOCK_TMS;
+
+void   clock_Init(void);
+void   clock_InitCounter(CLOCK_CLOCKS);
+void   clock_StartCounter(CLOCK_CLOCKS);
+void   clock_StopPassedTime(CLOCK_CLOCKS);
+void   clock_StopAddPassedTime(CLOCK_CLOCKS);
+float  clock_GetSeconds(CLOCK_CLOCKS);
+void   clock_PrintTime(CLOCK_CLOCKS);
+
+#ifdef WIN
+void clock_PingOneSecond(void);
+#endif
+
+#endif
diff --git a/test/spass/closure.c b/test/spass/closure.c
new file mode 100644
index 0000000000000000000000000000000000000000..cfebc7afccc2ab4909e55d14009350b54892af1a
--- /dev/null
+++ b/test/spass/closure.c
@@ -0,0 +1,441 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *             CONGRUENCE CLOSURE ALGORITHM               * */
+/* *                                                        * */
+/* *  $Module:   CLOSURE                                    * */
+/* *                                                        * */
+/* *  Copyright (C) 1999, 2000, 2001 MPI fuer Informatik    * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/**************************************************************/
+/* Include                                                    */
+/**************************************************************/
+
+#include "closure.h"
+
+
+/**************************************************************/
+/* Global constants and variable                              */
+/**************************************************************/
+
+/* standard initial size of a closure's stacks */
+static const int cc_RASSTDSIZE = 64;
+/* cc_RASSTDSIZE * ld(cc_RASSTDSIZE) */
+static const int cc_SIZELDSIZE = 384;
+/* the virtual term "true" has number 0 */
+static const ELEMENT cc_NOOFTRUE = 0;
+
+
+static struct {
+  PARTITION partition;
+  TABLE table;
+  RAS car, cdr, size, pending, combine;
+} cc_CLOSURE;
+
+/* the closure consists of a partition, a signature table, stacks for         */
+/* (circularly linked) lists of predecessors of equivalence classes (i. e.    */
+/* terms with direct subterms from this class), for the sizes of these lists, */
+/* for pending terms (the ones to be worked off) and for terms to be combined */
+/* in the same equivalence class                                              */
+
+
+/**************************************************************/
+/* Inline functions                                           */
+/**************************************************************/
+
+static __inline__ PARTITION cc_GetPartition(void)
+{
+  return cc_CLOSURE.partition;
+}
+
+
+static __inline__ void cc_SetPartition(PARTITION partition)
+{
+  cc_CLOSURE.partition = partition;
+}
+
+
+static __inline__ TABLE cc_GetTable(void)
+{
+  return cc_CLOSURE.table;
+}
+
+
+static __inline__ void cc_SetTable(TABLE table)
+{
+  cc_CLOSURE.table = table;
+}
+
+
+static __inline__ RAS cc_GetCars(void)
+{
+  return cc_CLOSURE.car;
+}
+
+
+static __inline__ TERM cc_GetCar(int index)
+{
+  return (TERM) ras_Get(cc_GetCars(), index);
+}
+
+
+static __inline__ void cc_SetCars(RAS car)
+{
+  cc_CLOSURE.car = car;
+}
+
+
+static __inline__ RAS cc_GetCdrs(void)
+{
+  return cc_CLOSURE.cdr;
+}
+
+
+static __inline__ int cc_GetCdr(int index)
+{
+  return (int) ras_Get(cc_GetCdrs(), index);
+}
+
+
+static __inline__ void cc_SetCdrs(RAS cdr)
+{
+  cc_CLOSURE.cdr = cdr;
+}
+
+
+static __inline__ void cc_SetCdr(int index, int cdr)
+{
+  ras_Set(cc_GetCdrs(), index, (POINTER) cdr);
+}
+
+
+static __inline__ RAS cc_GetSizes(void)
+{
+  return cc_CLOSURE.size;
+}
+
+
+static __inline__ int cc_GetSize(int index)
+{
+  return (int) ras_Get(cc_GetSizes(), index);
+}
+
+
+static __inline__ void cc_SetSizes(RAS size)
+{
+  cc_CLOSURE.size = size;
+}
+
+
+static __inline__ void cc_SetSize(int index, int size)
+{
+  ras_Set(cc_GetSizes(), index, (POINTER) size);
+}
+
+
+static __inline__ RAS cc_GetPending(void)
+{
+  return cc_CLOSURE.pending;
+}
+
+
+static __inline__ void cc_SetPending(RAS pending)
+{
+  cc_CLOSURE.pending = pending;
+}
+
+
+static __inline__ RAS cc_GetCombine(void)
+{
+  return cc_CLOSURE.combine;
+}
+
+
+static __inline__ void cc_SetCombine(RAS combine)
+{
+  cc_CLOSURE.combine = combine;
+}
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+static int cc_Number(int actno, TERM term, TERM pred)
+/***************************************************************
+  INPUT:   the actual number of terms, the term to be numbered
+           and its predecessor (may be the empty term
+           term_Null())
+  RETURNS: the new number of terms after recursively numbering
+           the term and its subterms
+  EFFECT:  stores a term's number as its size, partially
+           initializes its predecessor list and pushes all
+           subterms to the pending stack
+***************************************************************/
+{
+  LIST terms;
+
+#ifdef CHECK
+  if (actno < 0) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cc_Number: negative actual number of terms.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  term_SetSize(term, actno++);
+  cc_SetCars(ras_Push(cc_GetCars(), pred));
+  cc_SetPending(ras_Push(cc_GetPending(), term));
+  for (terms = term_ArgumentList(term); !list_Empty(terms); terms =
+      list_Cdr(terms))
+    actno = cc_Number(actno, list_Car(terms), term);
+  return actno;
+}
+
+
+static void cc_Union(ECLASS c1, ECLASS c2)
+/***************************************************************
+  EFFECT:  unions c1 and c2, therefore the signatures of the
+           predecessors of one class change, so these
+           predecessors have to be deleted from the signature
+           table and become pending again; sets new class's
+           predecessor list and its size to the concatenation of
+           the old lists resp. the sum of the old sizes
+***************************************************************/
+{
+  int aux, size;
+  TERM term;
+
+#ifdef CHECK
+  if (part_Find(cc_GetPartition(), c1) != c1) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cc_Union: first class corrupted, i. e. is not ");
+    misc_ErrorReport("the representative.");
+    misc_FinishErrorReport();
+  }
+  if (part_Find(cc_GetPartition(), c2) != c2) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cc_Union: second class corrupted, i. e. is not ");
+    misc_ErrorReport("the representative.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (c1 != c2) {
+
+    /* make c1 the class with the bigger (or at least not smaller) list: */
+    if (cc_GetSize(c1) < cc_GetSize(c2)) {
+      aux = c1;
+      c1  = c2;
+      c2  = aux;
+    }
+
+    /* delete c2's predecessors from signature table and add them to pending: */
+    for (size = cc_GetSize(c2), aux = c2; size > 0; size--) {
+      term = cc_GetCar(aux);
+      aux  = cc_GetCdr(aux);
+      table_Delete(cc_GetTable(), term);
+      cc_SetPending(ras_Push(cc_GetPending(), term));
+    }
+
+    if (cc_GetSize(c2) > 0) {  /* then GetSize(c1) ( >= GetSize(c2) ) > 0 too */
+
+      /* union circularly linked lists by exchanging cdrs: */
+      aux = cc_GetCdr(c1);
+      cc_SetCdr(c1, cc_GetCdr(c2));
+      cc_SetCdr(c2, aux);
+
+      cc_SetSize(c1, cc_GetSize(c1) + cc_GetSize(c2));
+    }
+    part_Union(cc_GetPartition(), c1, c2);
+  }
+}
+
+
+static void cc_InitData(CLAUSE clause)
+/***************************************************************
+  INPUT:  the clause to investigate
+  EFFECT: pushes clause's atoms and their subterms on the
+          pending stack, initializes each predecessor list with
+          the list containing only a term's father, and unions
+          the equivalence classes of the terms of the same
+          antecedent equation
+***************************************************************/
+{
+  int last, actno, i, ld;
+  TERM atom;
+  RAS cdr, size;
+
+  cc_SetCars(ras_InitWithSize(cc_GetCars(), cc_RASSTDSIZE));
+  cc_SetPending(ras_InitWithSize(cc_GetPending(), cc_RASSTDSIZE));
+  ras_FastPush(cc_GetCars(), term_Null());  /* "true" has no predecessors */
+  actno = 1;
+  last  = clause_LastLitIndex(clause);
+  for (i = clause_FirstLitIndex(); i <= last; i++) {
+    atom = clause_GetLiteralAtom(clause, i);
+    if (fol_IsEquality(atom)) {
+      actno = cc_Number(actno, term_FirstArgument(atom), term_Null());
+      actno = cc_Number(actno, term_SecondArgument(atom), term_Null());
+    }
+    else
+      actno = cc_Number(actno, atom, term_Null());
+  }
+  cc_SetPartition(part_Init(cc_GetPartition(), actno));
+  cc_SetTable(table_Init(cc_GetTable(), symbol_ActIndex() - 1,
+                         clause_MaxVar(clause), actno - 1));
+  cdr  = ras_InitWithSize(cc_GetCdrs(), actno);
+  size = ras_InitWithSize(cc_GetSizes(), actno);
+  for (i = 0; i < actno; i++) {
+    ras_FastPush(cdr, (POINTER) i);  /* form a cycle */
+    ras_FastPush(size, (POINTER) (cc_GetCar(i) == term_Null()? 0 : 1));
+  }
+  cc_SetCdrs(cdr);
+  cc_SetSizes(size);
+
+  /* compute ceil(ld(actno)) avoiding mathbib-logarithm's rounding errors: */
+  for (ld = 0, i = actno - 1; i > 0; i >>= 1)
+    ld++;
+
+  cc_SetCombine(ras_InitWithSize(cc_GetCombine(), actno * ld + 1));
+
+  /* for every antecedent equation union equivalence classes of its terms  */
+  /* (a non-equational atom is represented as the equation atom = "true"): */
+  last = clause_LastAntecedentLitIndex(clause);
+  for (i = clause_FirstLitIndex(); i <= last; i++) {
+    atom = clause_GetLiteralAtom(clause, i);
+    if (fol_IsEquality(atom))
+      cc_Union(term_Size(term_FirstArgument(atom)),  /* clause not shared, therefore */
+	       term_Size(term_SecondArgument(atom))); /* here no cc_Find needed */
+    else
+      cc_Union(term_Size(atom), part_Find(cc_GetPartition(), cc_NOOFTRUE));
+  }
+
+}
+
+
+static BOOL cc_Outit(CLAUSE clause)
+/***************************************************************
+  RETURNS: the decision, if the clause is a tautology
+***************************************************************/
+{
+  int last, i;
+  BOOL result;
+  TERM atom;
+
+#ifdef CHECK
+  if (!ras_Empty(cc_GetPending())) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cc_Outit: there are terms left to work off.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  last   = clause_LastLitIndex(clause);
+  for (i = clause_FirstSuccedentLitIndex(clause), result = FALSE;
+       i <= last && !result; i++) {
+    atom = clause_GetLiteralAtom(clause, i);
+    if (fol_IsEquality(atom))
+      result = part_Equivalent(cc_GetPartition(),
+			       term_Size(term_FirstArgument(atom)),
+			       term_Size(term_SecondArgument(atom)));
+    else
+      result = part_Equivalent(cc_GetPartition(), term_Size(atom), cc_NOOFTRUE);
+  }
+  return result;
+}
+
+
+/**************************************************************/
+/* Main functions                                             */
+/**************************************************************/
+
+void cc_Init(void)
+{
+  cc_SetPartition(part_Create(cc_RASSTDSIZE));
+  cc_SetTable(table_Create(cc_RASSTDSIZE, cc_RASSTDSIZE, cc_RASSTDSIZE));
+  cc_SetCars(ras_CreateWithSize(cc_RASSTDSIZE));
+  cc_SetCdrs(ras_CreateWithSize(cc_RASSTDSIZE));
+  cc_SetSizes(ras_CreateWithSize(cc_RASSTDSIZE));
+  cc_SetPending(ras_CreateWithSize(cc_RASSTDSIZE));
+  cc_SetCombine(ras_CreateWithSize(cc_SIZELDSIZE));
+}
+
+
+void cc_Free(void)
+{
+  part_Free(cc_GetPartition());
+  table_Free(cc_GetTable());
+  ras_Free(cc_GetCars());
+  ras_Free(cc_GetCdrs());
+  ras_Free(cc_GetSizes());
+  ras_Free(cc_GetPending());
+  ras_Free(cc_GetCombine());
+}
+
+
+BOOL cc_Tautology(CLAUSE clause)
+/***************************************************************
+  INPUT:   the clause to test
+  RETURNS: the decision, if the clause - where all variables are
+           regarded as skolem constants - is a tautology, using
+           the congruence closure algorithm of Downey, Sethi and
+           Tarjan
+  CAUTION: overrides the sizes of the clause's terms
+***************************************************************/
+{
+  TERM term, query;
+
+  cc_InitData(clause);
+  while (!ras_Empty(cc_GetPending())) {
+
+    /* propagate the closure: */
+    while (!ras_Empty(cc_GetPending())) {
+      term  = ras_Pop(cc_GetPending());
+      query = table_QueryAndEnter(cc_GetTable(), cc_GetPartition(), term);
+      if (query != term_Null()) {
+        ras_FastPush(cc_GetCombine(), term);
+        ras_FastPush(cc_GetCombine(), query);
+      }
+    }
+    while (!ras_Empty(cc_GetCombine()))
+      cc_Union(part_Find(cc_GetPartition(), term_Size(ras_Pop(cc_GetCombine()))),
+	       part_Find(cc_GetPartition(), term_Size(ras_Pop(cc_GetCombine()))));
+  }
+  return cc_Outit(clause);
+}
+
diff --git a/test/spass/closure.h b/test/spass/closure.h
new file mode 100644
index 0000000000000000000000000000000000000000..0a6d5c046e1c31c5beccafa6fa2c22a1f9fd8484
--- /dev/null
+++ b/test/spass/closure.h
@@ -0,0 +1,67 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *             CONGRUENCE CLOSURE ALGORITHM               * */
+/* *                                                        * */
+/* *  $Module:   CLOSURE                                    * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1999, 2000, 2001 MPI fuer Informatik    * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+#ifndef _CLOSURE_
+#define _CLOSURE_
+
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "clause.h"
+#include "table.h"
+#include "ras.h"
+
+
+/**************************************************************/
+/* Prototype                                                  */
+/**************************************************************/
+
+void cc_Init(void);
+void cc_Free(void);
+BOOL cc_Tautology(CLAUSE);
+
+
+#endif
+
diff --git a/test/spass/cnf.c b/test/spass/cnf.c
new file mode 100644
index 0000000000000000000000000000000000000000..bf52a264f35919a7670f5d55bdeb4d994f2c8193
--- /dev/null
+++ b/test/spass/cnf.c
@@ -0,0 +1,4787 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *               CNF TRANSLATOR                           * */
+/* *                                                        * */
+/* *  $Module:   CNF                                        * */
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                       * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "cnf.h"
+#include "rules-inf.h"
+#include "rules-red.h"
+
+
+static TERM   cnf_AntiPrenexPath(TERM, TERM);
+static TERM   cnf_ApplyDefinitionInternOnce(TERM, TERM, TERM, TERM, BOOL*);
+
+static SYMBOL cnf_GetDualSymbol(SYMBOL symbol);
+
+static TERM   cnf_IsDefinition(TERM);
+
+static void   cnf_OptimizedSkolemFormula(PROOFSEARCH, TERM, char*, BOOL, TERM,
+					 LIST*, LIST*, BOOL, HASH, int);
+static int    cnf_PredicateOccurrences(TERM, SYMBOL);
+
+static void   cnf_RplacVar(TERM, LIST, LIST);
+
+static LIST   cnf_SatUnit(PROOFSEARCH, LIST);
+static LIST   cnf_SkolemFunctionFormula(TERM, LIST, LIST, PRECEDENCE);
+
+/* For every variable the depth in the current term, required for */
+/* strong skolemization */
+static int* cnf_VARIABLEDEPTHARRAY;
+/* Holds a copy of the ProofSearch--Object built by cnf_Flotter */
+/* during cnf_QueryFlotter */
+static PROOFSEARCH cnf_SEARCHCOPY;
+
+/* Proofsearch--Object for the function cnf_HaveProof. We need this */
+/* to reduce the number of term stamps required. */
+static PROOFSEARCH cnf_HAVEPROOFPS;
+
+
+void cnf_Init(FLAGSTORE Flags)
+/***************************************************************
+  INPUT:   A flag store.
+  RETURNS: None.
+  SUMMARY: Initializes the CNF Module.
+  EFFECTS: Initializes global variables.
+  CAUTION: MUST BE CALLED BEFORE ANY OTHER CNF-FUNCTION.
+***************************************************************/
+{
+  /* If strong skolemization is performed, allocate array for variable depth */
+  if (flag_GetFlagValue(Flags, flag_CNFSTRSKOLEM))
+    cnf_VARIABLEDEPTHARRAY = (int*) memory_Malloc(sizeof(int[symbol__MAXSTANDARDVAR + 1]));
+  else
+    cnf_VARIABLEDEPTHARRAY = NULL;
+  cnf_SEARCHCOPY  = prfs_Create();
+  cnf_HAVEPROOFPS = prfs_Create();
+}
+
+
+void cnf_Free(FLAGSTORE Flags)
+/**************************************************************
+  INPUT:   A flag store.
+  RETURNS: None.
+  SUMMARY: Frees the CNF Module.
+***************************************************************/
+{
+  /* If strong skolemization is performed, free array for variable depth */
+  if (flag_GetFlagValue(Flags, flag_CNFSTRSKOLEM)) {
+    memory_Free(cnf_VARIABLEDEPTHARRAY, sizeof(int) * (symbol__NOOFSTANDARDVAR + 1));
+    cnf_VARIABLEDEPTHARRAY = NULL;
+  }
+  prfs_Delete(cnf_SEARCHCOPY);
+  cnf_SEARCHCOPY = NULL;
+  prfs_Delete(cnf_HAVEPROOFPS);
+  cnf_HAVEPROOFPS = NULL;
+}
+
+
+static int cnf_GetFormulaPolarity(TERM term, TERM subterm)
+/**********************************************************
+  INPUT:   Two terms term and subterm where subterm is a
+           subterm of term.
+  RETURNS: The polarity of subterm in term.
+********************************************************/
+{  
+  LIST   scan;
+  TERM   term1;
+  int    polterm1,bottom; 
+
+  bottom = vec_ActMax();
+  vec_Push((POINTER) 1);
+  vec_Push(term);
+
+  do {
+    term1    = (TERM)vec_PopResult();
+    polterm1 = (int)vec_PopResult();
+    if (term1 == subterm) {
+      vec_SetMax(bottom);
+      return polterm1;
+    }else
+      if (symbol_Equal(term_TopSymbol(term1),fol_Not())) {
+	vec_Push((POINTER) (- polterm1));
+	vec_Push(list_Car(term_ArgumentList(term1)));
+      }
+    if (symbol_Equal(term_TopSymbol(term1),fol_Exist()) ||
+	symbol_Equal(term_TopSymbol(term1),fol_All())) {
+      vec_Push((POINTER)polterm1);
+      vec_Push(list_Second(term_ArgumentList(term1)));
+    }
+    else
+      if (symbol_Equal(term_TopSymbol(term1),fol_Implies())) {
+	vec_Push((POINTER) (- polterm1));
+	vec_Push(list_Car(term_ArgumentList(term1)));
+	vec_Push((POINTER) polterm1);
+	vec_Push(list_Second(term_ArgumentList(term1)));
+      }
+      else
+	if (symbol_Equal(term_TopSymbol(term1),fol_Equiv())) {
+	  vec_Push(0);
+	  vec_Push(list_Car(term_ArgumentList(term1)));
+	  vec_Push(0);
+	  vec_Push(list_Second(term_ArgumentList(term1)));
+	}
+	else
+	  if (symbol_Equal(term_TopSymbol(term1),fol_And()) ||
+	      symbol_Equal(term_TopSymbol(term1),fol_Or())) {
+	    for (scan = term_ArgumentList(term1);
+		 !list_Empty(scan);
+		 scan = list_Cdr(scan)) {
+	      vec_Push((POINTER) polterm1);
+	      vec_Push(list_Car(scan));
+	    }
+	  }
+  } while (bottom != vec_ActMax());
+  vec_SetMax(bottom);
+  misc_StartErrorReport();
+  misc_ErrorReport("\n In cnf_GetFormulaPolarity: Wrong arguments !\n");
+  misc_FinishErrorReport();
+  return -2;
+}
+
+
+static BOOL cnf_ContainsDefinitionIntern(TERM TopDef, TERM Def, int Polarity,
+					 TERM* FoundPred)
+/**********************************************************
+  INPUT:   A term TopDef which is the top level term of the recursion.
+           A term Def which is searched for a definition.
+           A pointer to a term into which the predicate of the definition
+	   is stored if it is found.
+  RETURNS: TRUE if Def contains a definition that can be converted
+           to standard form.
+********************************************************/
+{
+  /* AND / OR */
+  /* In these cases Def cannot be converted to standard form */
+
+  if ((symbol_Equal(term_TopSymbol(Def),fol_And()) && (Polarity == 1)) ||
+      (symbol_Equal(term_TopSymbol(Def),fol_Or()) && (Polarity == -1)))
+    return FALSE;
+
+  if (symbol_Equal(term_TopSymbol(Def), fol_And()) ||
+     symbol_Equal(term_TopSymbol(Def),fol_Or())) {
+    /* Polarity is ok */
+    LIST l;
+    for (l=term_ArgumentList(Def); !list_Empty(l); l=list_Cdr(l))
+      if (cnf_ContainsDefinitionIntern(TopDef, list_Car(l), Polarity, FoundPred))
+	return TRUE;
+    return FALSE;
+  }
+
+  /* Quantifiers */
+  if (fol_IsQuantifier(term_TopSymbol(Def)))
+    return cnf_ContainsDefinitionIntern(TopDef, term_SecondArgument(Def), Polarity, FoundPred);
+  
+  /* Negation */
+  if (symbol_Equal(term_TopSymbol(Def),fol_Not()))
+    return cnf_ContainsDefinitionIntern(TopDef, term_FirstArgument(Def), -Polarity, FoundPred);
+  
+  /* Implication */
+  if (symbol_Equal(term_TopSymbol(Def),fol_Implies())) {
+    if (Polarity==1) {
+      if (cnf_ContainsDefinitionIntern(TopDef, term_FirstArgument(Def), -Polarity, FoundPred))
+	return TRUE;
+      return cnf_ContainsDefinitionIntern(TopDef, term_SecondArgument(Def), Polarity, FoundPred);
+    }
+    return FALSE;
+  }
+  
+  /* Equivalence */
+  if (symbol_Equal(term_TopSymbol(Def),fol_Equiv()) && (Polarity==1)) {
+    /* Check if equivalence itself is in correct form */
+    TERM defpredicate;
+
+    defpredicate = cnf_IsDefinition(Def);
+    if (defpredicate != (TERM) NULL) {
+      LIST predicate_vars, l, defpath;
+      BOOL allquantifierfound;
+      TERM super;
+      int pol;
+      /* Check if predicate occurs several times in TopDef */
+      /* if (cnf_PredicateOccurrences(TopDef, term_TopSymbol(defpredicate)) > 1) {}
+	 puts("\n Predicate occurs more than once.");
+	 return FALSE; */
+
+
+      /* Now make sure that the variables of the predicate are       */
+      /* all--quantified and not in the scope of an exist quantifier */
+      /*      predicate_vars = list_Copy(term_ArgumentList(defpredicate)); */
+      predicate_vars = term_ListOfVariables(defpredicate);
+      predicate_vars = term_DeleteDuplicatesFromList(predicate_vars);
+
+      /* So far (going bottom--up) no all-quantifier was found for */
+      /* a variable of the predicates' arguments */
+      allquantifierfound = FALSE;
+      
+      /* Build defpath here by going bottom up */
+      /* At first, list of superterms on path is top down */
+      defpath = list_Nil();
+      super = Def;
+      while (super != (TERM) NULL) {
+	defpath = list_Cons(super, defpath);
+	super = term_Superterm(super);
+      }
+      /* No go top down and add polarities */
+      pol = 1;
+      for (l=defpath; !list_Empty(l); l=list_Cdr(l)) {
+	list_Rplaca(l, list_PairCreate((TERM) list_Car(l), (LIST) pol));
+	if (symbol_Equal(term_TopSymbol((TERM) list_Car(l)), fol_Not()))
+	  pol = -pol;
+	else {
+	  if (symbol_Equal(term_TopSymbol((TERM) list_Car(l)), fol_Implies()) &&
+	      (term_FirstArgument((TERM) list_Car(l)) == (TERM) list_Car(list_Cdr(l))))
+	    pol = -pol;
+	  else 
+	    if (symbol_Equal(term_TopSymbol((TERM) list_Car(l)), fol_Equiv()))
+	      pol = 0;
+	}
+      }
+      /* <defpath> is now a list of pairs (term, polarity) */
+      for (l=defpath; !list_Empty(l) && !list_Empty(predicate_vars); l=list_Cdr(l)) {
+	LIST pair;
+	TERM t;
+	int p;
+	/* Pair Term t / Polarity p */
+	pair = (LIST) list_Car(l);
+	t = (TERM) list_PairFirst(pair);
+	p = (int) list_PairSecond(pair);
+
+	if (fol_IsQuantifier(term_TopSymbol(t))) {
+	  
+	  /* Variables of the predicate that are universally quantified are no problem */
+	  if ((symbol_Equal(term_TopSymbol(t), fol_All()) && (p==1)) ||
+	      (symbol_Equal(term_TopSymbol(t), fol_Exist()) && (p==-1))) {
+	    LIST scan;
+	    allquantifierfound = TRUE;
+	    for (scan=fol_QuantifierVariables(t); !list_Empty(scan); scan=list_Cdr(scan))
+	      predicate_vars = list_DeleteElement(predicate_vars,(TERM) list_Car(scan),
+						  (BOOL (*)(POINTER,POINTER))term_Equal);
+	  }
+	  else {
+	    /* Check if allquantified variables of the predicate are in scope of an exist--quantifier */
+	    /* We already found an all quantified variable */
+	    if (allquantifierfound) {
+	      list_Delete(predicate_vars);
+	      list_DeletePairList(defpath);
+	      return FALSE;
+	    }
+	    else {
+	      LIST scan;
+	      /* Check if a variable of the predicate is exist--quantified */
+	      for (scan=fol_QuantifierVariables(t); !list_Empty(scan); scan=list_Cdr(scan)) {
+		if (term_ListContainsTerm(predicate_vars, list_Car(scan))) {
+		  list_Delete(predicate_vars);
+		  list_DeletePairList(defpath);
+		  return FALSE;
+		}
+	      }
+	    }
+	  }
+	}
+      }
+      
+#ifdef CHECK
+      if (!list_Empty(predicate_vars)) {
+	list_Delete(predicate_vars);
+	misc_StartErrorReport();
+	misc_ErrorReport("\n In cnf_ContainsDefinitionIntern: Definition has free variables.\n");
+	misc_FinishErrorReport();
+      }
+#endif
+      list_DeletePairList(defpath);
+      *FoundPred = defpredicate;
+      return TRUE;
+    }
+  }
+  
+  return FALSE;
+}
+
+
+BOOL cnf_ContainsDefinition(TERM Def, TERM* FoundPred)
+/**********************************************************
+  INPUT:   A term Def which is searched for a definition of a predicate.
+           A pointer to a term into which the predicate of the definition
+	   is stored if it is found.
+  RETURNS: TRUE if Def contains a definition that can be converted to
+           standard form.
+***********************************************************/
+{
+  BOOL result;
+#ifdef CHECK
+  fol_CheckFatherLinks(Def);
+#endif
+  result = cnf_ContainsDefinitionIntern(Def, Def, 1, FoundPred);
+#ifdef CHECK
+  fol_CheckFatherLinks(Def);
+#endif
+  return result;
+}
+
+
+static TERM cnf_IsDefinition(TERM Def)
+/**********************************************************
+ INPUT:   A term Def.
+ RETURNS: The Def term where the arguments of the equivalence are exchanged
+          iff the first one is not a predicate.
+**********************************************************/
+{
+  LIST l,freevars, predicatevars;
+
+#ifdef CHECK
+  if (Def == NULL) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cnf_IsDefinition: Empty formula.\n");
+    misc_FinishErrorReport();
+  }
+  if (!symbol_Equal(term_TopSymbol(Def),fol_Equiv())) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cnf_IsDefinition: Formula is no equivalence.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  /* If the predicate is the second argument of the equivalence, exchange them */
+  if (!symbol_IsPredicate(term_TopSymbol(term_FirstArgument(Def)))) {
+    TERM arg1;
+    arg1 = term_FirstArgument(Def);
+    term_RplacFirstArgument(Def, term_SecondArgument(Def));
+    term_RplacSecondArgument(Def, arg1);
+  }
+
+
+  /* Check if the first argument is a predicate */
+  if (!symbol_IsPredicate(term_TopSymbol(term_FirstArgument(Def)))) 
+    return NULL;
+
+  /* Check if first argument is a predicate and not fol_Equality */
+  /*  if (!symbol_IsPredicate(term_TopSymbol(term_FirstArgument(Def)))
+      || symbol_Equal(term_TopSymbol(term_FirstArgument(Def)), fol_Equality()))) {
+      return NULL;
+      }*/
+
+
+  /* The free variables of the non-predicate term must occur in the predicate term */
+  
+  freevars = fol_FreeVariables(term_SecondArgument(Def));
+  freevars = term_DeleteDuplicatesFromList(freevars);
+  predicatevars = term_ListOfVariables(term_FirstArgument(Def));
+  predicatevars = term_DeleteDuplicatesFromList(predicatevars);
+
+  for (l=predicatevars; !list_Empty(l); l=list_Cdr(l))
+    freevars = list_DeleteElement(freevars, list_Car(l),
+				  (BOOL (*)(POINTER,POINTER))term_Equal);
+
+  if (!list_Empty(freevars)) {
+    list_Delete(freevars);
+    list_Delete(predicatevars);
+    return NULL;
+  }
+
+  list_Delete(predicatevars);
+  return term_FirstArgument(Def);
+}
+
+
+static BOOL cnf_ContainsPredicateIntern(TERM Target, SYMBOL Predicate, 
+					int Polarity, TERM* TargetPredicate,
+					TERM* ToTopLevel, LIST* TargetVars,
+					LIST* VarsForTopLevel)
+/**********************************************************
+  INPUT:   A term (sub--) Target
+           A symbol Predicate which is searched in the target term.
+           The polarity of the subterm.
+           A pointer to the term TargetPredicate into which the found
+	   predicate term is stored.
+           A pointer to the list TargetVars into which the variables found
+	   in the predicates' arguments are stored.
+           A pointer to a list VarsForTopLevel into which all variables are
+	   stored that are all--quantified and can be moved to top level.
+
+  RETURNS: TRUE if Formula contains the predicate for which a definition
+           was found.
+********************************************************/
+{
+  /* AND / OR */
+  /* In these cases the predicate (if it exists) can not be moved to a higher level */
+
+  if ((symbol_Equal(term_TopSymbol(Target),fol_And()) && Polarity == 1) ||
+      (symbol_Equal(term_TopSymbol(Target),fol_Or()) && Polarity == -1) ||
+      (symbol_Equal(term_TopSymbol(Target),fol_Implies()) && Polarity != 1) ||
+      symbol_Equal(term_TopSymbol(Target), fol_Equiv())) {
+    TERM s;
+    LIST l;
+    /* Try to find Predicate in Target */
+    s = term_FindSubterm(Target, Predicate);
+    if (s == NULL)
+      return FALSE;
+    
+    /* Store variables found in the predicates arguments */
+    for (l=term_ArgumentList(s); !list_Empty(l); l = list_Cdr(l))
+      *TargetVars = list_Nconc(fol_FreeVariables((TERM) list_Car(l)), *TargetVars);
+    *TargetVars = term_DeleteDuplicatesFromList(*TargetVars);
+    /* Keep found predicate */
+    *TargetPredicate = s;
+    *ToTopLevel = Target;
+    return TRUE;
+  }
+  
+  /* AND / OR continued */
+  if (symbol_Equal(term_TopSymbol(Target),fol_And()) || symbol_Equal(term_TopSymbol(Target),fol_Or())) {
+    /* The polarity is ok here */
+    LIST l;
+    for (l=term_ArgumentList(Target); !list_Empty(l); l = list_Cdr(l))
+      if (cnf_ContainsPredicateIntern((TERM) list_Car(l), Predicate, Polarity,
+				      TargetPredicate, ToTopLevel, TargetVars,
+				      VarsForTopLevel))
+	return TRUE;
+    return FALSE;
+  }
+
+  /* Quantifiers */
+  if (fol_IsQuantifier(term_TopSymbol(Target))) {
+    if (cnf_ContainsPredicateIntern(term_SecondArgument(Target), Predicate,
+				    Polarity, TargetPredicate, ToTopLevel,
+				    TargetVars, VarsForTopLevel)) {
+      /* Quantifiers for free variables of the predicate should be moved
+	 to top level to make the proof easier */
+      if ((symbol_Equal(term_TopSymbol(Target), fol_All()) && Polarity == 1) ||
+	  (symbol_Equal(term_TopSymbol(Target), fol_Exist()) && Polarity == -1)) {
+	LIST l;
+	/* Check for all variables found in the predicates arguments */
+	for (l = *TargetVars; !list_Empty(l); l=list_Cdr(l)) {
+	  if (term_ListContainsTerm(fol_QuantifierVariables(Target),list_Car(l)))
+	    *VarsForTopLevel = list_Cons(list_Car(l), *VarsForTopLevel);
+	}
+      }
+      return TRUE;
+    }
+    return FALSE;
+  }
+
+  /* Negation */
+  if (symbol_Equal(term_TopSymbol(Target),fol_Not()))
+    return cnf_ContainsPredicateIntern(term_FirstArgument(Target), Predicate,
+				       -Polarity, TargetPredicate, ToTopLevel,
+				       TargetVars, VarsForTopLevel);
+  /* Implication */
+  if (symbol_Equal(term_TopSymbol(Target),fol_Implies())) {
+    /* In this case the predicate (if it exists) can be moved to a higher level */
+    if (cnf_ContainsPredicateIntern(term_FirstArgument(Target), Predicate,
+				    -Polarity, TargetPredicate, ToTopLevel,
+				    TargetVars, VarsForTopLevel))
+      return TRUE;
+    return cnf_ContainsPredicateIntern(term_SecondArgument(Target), Predicate,
+				       Polarity, TargetPredicate, ToTopLevel,
+				       TargetVars, VarsForTopLevel);
+  }
+
+  /* Found the predicate */
+  if (symbol_Equal(term_TopSymbol(Target), Predicate)) {
+    LIST l;
+    for (l = term_ArgumentList(Target); !list_Empty(l); l = list_Cdr(l))
+      *TargetVars = list_Nconc(fol_FreeVariables((TERM) list_Car(l)), *TargetVars);
+    *TargetVars = term_DeleteDuplicatesFromList(*TargetVars);
+    
+    *TargetPredicate = Target;
+    *ToTopLevel      = Target;
+    return TRUE;
+  }
+  
+  /* In all other cases the predicate was not found */
+  return FALSE;
+}  
+
+  
+BOOL cnf_ContainsPredicate(TERM Target, SYMBOL Predicate,
+			   TERM* TargetPredicate, TERM* ToTopLevel,
+			   LIST* TargetVars, LIST* VarsForTopLevel)
+/**********************************************************
+  INPUT:   A term Target without implications.
+           A symbol Predicate which is searched in the target term.
+           A pointer to the predicate found in TargetTerm is recorded.
+           A pointer to the term TargetPredicate into which the found
+	   predicate term is stored.
+           A pointer to the list TargetVars into which the variables
+	   found in the predicates' arguments are stored.
+           A pointer to a list VarsForTopLevel into which all variables
+	   are stored that are all--quantified and can be moved to top level.
+  RETURNS: TRUE if Formula contains the predicate for which a definition
+           was found.
+********************************************************/
+{
+  BOOL result;
+#ifdef CHECK
+  fol_CheckFatherLinks(Target);
+#endif
+  result = cnf_ContainsPredicateIntern(Target, Predicate, 1, TargetPredicate,
+				       ToTopLevel, TargetVars, VarsForTopLevel);
+#ifdef CHECK
+  fol_CheckFatherLinks(Target);
+#endif
+  return result;
+}
+
+
+static int cnf_PredicateOccurrences(TERM Term, SYMBOL P)
+/****************************************************
+  INPUT:   A term and a predicate symbol.
+  RETURNS: The number of occurrences of the predicate symbol in Term
+**************************************************/			       
+{
+  /* Quantifiers */
+  if (fol_IsQuantifier(term_TopSymbol(Term)))
+    return cnf_PredicateOccurrences(term_SecondArgument(Term), P);
+
+  /* Junctors and NOT */
+  if (fol_IsJunctor(term_TopSymbol(Term)) ||
+      symbol_Equal(term_TopSymbol(Term),fol_Not())) {
+    LIST scan;
+    int count;
+    count = 0;
+    for (scan=term_ArgumentList(Term); !list_Empty(scan); scan=list_Cdr(scan)) {
+      count += cnf_PredicateOccurrences(list_Car(scan), P);
+      /* Only the cases count==1 and count>1 are important */
+      if (count > 1)
+	return count;
+    }
+    return count;
+  }
+  
+  if (symbol_Equal(term_TopSymbol(Term), P))
+    return 1;
+  return 0;
+} 
+  
+
+static TERM cnf_NegationNormalFormulaPath(TERM Term, TERM PredicateTerm)
+/**********************************************************
+  INPUT:   A term and a predicate term which is a subterm of term
+  RETURNS: The negation normal form of the term along the path.
+  CAUTION: The term is destructively changed.
+           This works only if the superterm member of Term and its subterms 
+	   are set.
+********************************************************/
+{
+  TERM   subterm, termL, term1;
+  LIST   scan;
+  SYMBOL symbol;
+  BOOL   set;
+
+  term1 = Term;
+  while (term1 != NULL) {
+    set = FALSE;
+    if (symbol_Equal(term_TopSymbol(term1),fol_Not())) {	    
+      subterm = term_FirstArgument(term1);
+      if (symbol_Equal(term_TopSymbol(subterm),fol_Not())) {
+	LIST l;
+	term_RplacTop(term1,term_TopSymbol(term_FirstArgument(subterm)));
+	list_Delete(term_ArgumentList(term1));
+	term_RplacArgumentList(term1,term_ArgumentList(term_FirstArgument(subterm)));
+	term_Free(term_FirstArgument(subterm));
+	list_Delete(term_ArgumentList(subterm));
+	term_Free(subterm);
+	/* Set superterm member to new superterm */
+	for (l=term_ArgumentList(term1); !list_Empty(l); l=list_Cdr(l))
+	  term_RplacSuperterm(list_Car(l), term1);
+	/* term1 weiter betrachten */
+	set = TRUE;
+      }
+      else {
+	if (fol_IsQuantifier(term_TopSymbol(subterm))) {
+	  LIST l;
+	  symbol = (SYMBOL)cnf_GetDualSymbol(term_TopSymbol(subterm));
+	  termL  = term_CreateAddFather(fol_Not(),
+					list_List(term_SecondArgument(subterm)));
+	  list_RplacSecond(term_ArgumentList(subterm), termL);
+	  term_RplacSuperterm(termL, subterm);
+	  term_RplacTop(term1,symbol);
+	  list_Delete(term_ArgumentList(term1));
+	  term_RplacArgumentList(term1, term_ArgumentList(subterm));
+	  for (l=term_ArgumentList(term1); !list_Empty(l); l = list_Cdr(l))
+	    term_RplacSuperterm(list_Car(l), term1);
+	  term_RplacArgumentList(subterm, list_Nil());
+	  term_Delete(subterm);
+	  term1 = termL;
+	  /* Next term to check is not(subterm) */
+	  set = TRUE;
+	} 
+	else {
+	  if (symbol_Equal(term_TopSymbol(subterm),fol_Or()) || 
+	      (symbol_Equal(term_TopSymbol(subterm),fol_And()))) {
+	    LIST l;
+	    symbol = (SYMBOL)cnf_GetDualSymbol(term_TopSymbol(subterm));
+	    for (scan = term_ArgumentList(subterm); !list_Empty(scan);
+		 scan = list_Cdr(scan)) {
+	      TERM new;
+	      termL = list_Car(scan);
+	      new = term_CreateAddFather(fol_Not(),list_List(termL));
+	      list_Rplaca(scan, new);
+	      term_RplacSuperterm(new, subterm);
+	    }
+	    term_RplacTop(term1,symbol);
+	    list_Delete(term_ArgumentList(term1));
+	    term_RplacArgumentList(term1,term_ArgumentList(subterm));
+	    for (l = term_ArgumentList(term1); !list_Empty(l); l=list_Cdr(l))
+	      term_RplacSuperterm(list_Car(l), term1);
+	    term_RplacArgumentList(subterm, list_Nil());
+	    term_Delete(subterm);
+	  }
+	}
+      }
+    }
+    if (!set) {
+      if (!list_Empty(term_ArgumentList(term1)))
+	for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan))
+	  if (term_HasProperSuperterm(PredicateTerm, list_Car(scan))) {
+	    term1 = list_Car(scan);
+	    set = TRUE;
+	    break;
+	  }
+      if (!set)
+	term1 = NULL;
+    }
+  }
+  return Term;
+}
+
+
+TERM cnf_ApplyDefinitionOnce(TERM Predicate, TERM Formula, TERM TargetTerm,
+			     TERM TargetPredicate, FLAGSTORE Flags)
+/*********************************************************
+  INPUT:   A term Predicate which is a predicate found in a definition.
+           A term Formula which is a term equivalent to the predicate.
+           A term TargetTerm in which one occurrence of the predicate may be 
+           replaced by the Formula.
+           A term TargetPredicate which is the subterm of the TargetTerm
+           to be replaced.
+	   A flag store.
+  RETURNS: The changed TargetTerm.
+*************************************************************/
+{
+  SYMBOL maxvar, maxvar_temp;
+  LIST bound, scan;
+  BOOL success;
+  
+  /* Init varcounter */
+  maxvar = term_MaxVar(TargetTerm);
+  maxvar_temp = term_MaxVar(Formula);
+  if (maxvar_temp > maxvar)
+    maxvar = maxvar_temp;
+  symbol_SetStandardVarCounter(maxvar);
+
+  /* Find bound variables in formula for renaming them */
+  bound = fol_BoundVariables(Formula);
+  for (scan=bound; !list_Empty(scan); scan=list_Cdr(scan)) {
+    /* Bound variable in definition is already used in term */
+    if (term_ContainsSymbol(TargetTerm, term_TopSymbol(list_Car(scan))))
+      term_ExchangeVariable(Formula, term_TopSymbol(list_Car(scan)),
+			    symbol_CreateStandardVariable());
+  }
+  list_Delete(bound);
+  TargetTerm = cnf_ApplyDefinitionInternOnce(Predicate, Formula, TargetTerm, 
+					     TargetPredicate,&success);
+  if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) {
+    if (success) {
+      fputs("\nTarget after applying def:\n", stdout);
+      fol_PrettyPrint(TargetTerm);
+      puts("\n");
+    }
+  }
+  
+  return TargetTerm;
+}
+
+
+static TERM cnf_ApplyDefinitionInternOnce(TERM Predicate, TERM Formula, 
+					  TERM TargetTerm, TERM TargetPredicate,
+					  BOOL* Success)
+/**********************************************************
+  INPUT:   A term Predicate which is equivalence to
+           Formula and Term
+  RETURNS: The term in which all occurrences of P(..) are 
+           replaced by Formula modulo the proper bindings
+  CAUTION: Term is destructively changed!
+***********************************************************/
+{
+  /* Quantifiers */
+  if (fol_IsQuantifier(term_TopSymbol(TargetTerm))) {
+    term_RplacSecondArgument(TargetTerm, 
+      cnf_ApplyDefinitionInternOnce(Predicate, Formula, 
+				    term_SecondArgument(TargetTerm),
+				    TargetPredicate, Success));
+    term_RplacSuperterm(term_SecondArgument(TargetTerm), TargetTerm);
+    return TargetTerm;
+  }
+
+  /* Junctors and NOT */
+  if (fol_IsJunctor(term_TopSymbol(TargetTerm)) ||
+      symbol_Equal(term_TopSymbol(TargetTerm),fol_Not())) {
+    LIST scan;
+    for (scan=term_ArgumentList(TargetTerm); !list_Empty(scan); scan=list_Cdr(scan)) {
+      list_Rplaca(scan, cnf_ApplyDefinitionInternOnce(Predicate, Formula, 
+						      list_Car(scan), 
+						      TargetPredicate, Success));
+      term_RplacSuperterm((TERM) list_Car(scan), TargetTerm);
+    }
+    return TargetTerm;
+  }
+  
+  if (symbol_Equal(term_TopSymbol(TargetTerm), term_TopSymbol(Predicate))) {
+    if (TargetTerm == TargetPredicate) {
+      TERM result;
+      result = Formula;
+      cnf_RplacVar(result, term_ArgumentList(Predicate), 
+		   term_ArgumentList(TargetTerm));
+      term_AddFatherLinks(result);
+      term_Delete(TargetTerm);
+      *Success = TRUE;
+      return result;
+    }
+  }
+  
+  return TargetTerm;
+} 
+
+
+static TERM cnf_RemoveEquivImplFromFormula(TERM term)
+/**********************************************************
+  INPUT:   A term.
+  RETURNS: The term  with replaced implications and equivalences.
+  CAUTION: The term is destructively changed.
+********************************************************/
+{
+  TERM term1,termL,termR,termLneg,termRneg;
+  LIST scan;
+  int  bottom,pol;
+  
+  bottom = vec_ActMax();
+  vec_Push(term);
+
+  while (bottom != vec_ActMax()) {
+    term1 = (TERM)vec_PopResult();
+    if (symbol_Equal(term_TopSymbol(term1),fol_Implies())) {
+      term_RplacTop(term1, fol_Or());
+      list_Rplaca(term_ArgumentList(term1),
+		  term_Create(fol_Not(), list_List(list_Car(term_ArgumentList(term1)))));
+    }else
+      if (symbol_Equal(term_TopSymbol(term1),fol_Equiv())) {
+	pol      = cnf_GetFormulaPolarity(term,term1);
+	termL    = (TERM)list_Car(term_ArgumentList(term1));
+	termR    = (TERM)list_Second(term_ArgumentList(term1));
+	termLneg = term_Create(fol_Not(),list_List(term_Copy(termL)));
+	termRneg = term_Create(fol_Not(),list_List(term_Copy(termR)));
+	if (pol == 1 || pol == 0) {
+	  term_RplacTop(term1, fol_And());
+	  list_Rplaca(term_ArgumentList(term1), term_Create(fol_Or(),list_Cons(termLneg,list_List(termR))));
+	  list_RplacSecond(term_ArgumentList(term1),term_Create(fol_Or(),list_Cons(termRneg,list_List(termL))));
+	}else
+	  if (pol == -1) {
+	    term_RplacTop(term1, fol_Or());
+	    list_Rplaca(term_ArgumentList(term1), term_Create(fol_And(),list_Cons(termLneg,list_List(termRneg))));
+	    list_RplacSecond(term_ArgumentList(term1), term_Create(fol_And(),list_Cons(termL,list_List(termR))));
+	  }
+      }  
+    if (!list_Empty(term_ArgumentList(term1)))
+      for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan))
+	vec_Push(list_Car(scan));
+  }
+  vec_SetMax(bottom);
+  return term;
+}
+
+
+static TERM cnf_MovePredicateVariablesUp(TERM Term, TERM TargetPredicateTerm,
+					 LIST VarsForTopLevel)
+/**********************************************************
+  INPUT:   A term and a predicate term which is a subterm of term
+           an equivalence.
+  RETURNS: The term where the free variables of the equivalence, which
+           must be allquantified and not in the scope of an 
+	   exist quantifier, are moved to toplevel.
+  CAUTION: The term is destructively changed.
+********************************************************/
+{
+  TERM term1;
+  LIST scan;
+  int  bottom;
+
+  bottom = vec_ActMax();
+  vec_Push(Term);
+  
+  while (bottom != vec_ActMax()) {
+    term1 = (TERM)vec_PopResult();
+    if (!list_Empty(term_ArgumentList(term1)))
+      for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan)) {
+	TERM arg;
+	arg = (TERM) list_Car(scan);
+	if (term_HasProperSuperterm(TargetPredicateTerm, arg)) {
+	  if (symbol_Equal(term_TopSymbol(arg), fol_All())) {
+	    LIST predicatevarscan, quantifiervars;
+	    quantifiervars = fol_QuantifierVariables(arg);
+	    for (predicatevarscan=VarsForTopLevel; !list_Empty(predicatevarscan);
+		predicatevarscan = list_Cdr(predicatevarscan))
+	      quantifiervars = list_DeleteElementFree(quantifiervars, 
+						      (TERM) list_Car(predicatevarscan),
+						      (BOOL (*)(POINTER,POINTER))term_Equal,
+						      (void (*)(POINTER))term_Delete);
+	    if (!list_Empty(quantifiervars))
+	      term_RplacArgumentList(term_FirstArgument(arg), quantifiervars);
+	    else {
+	      TERM subterm;
+	      subterm = term_SecondArgument(arg);
+	      term_Free(term_FirstArgument(arg));
+	      list_Delete(term_ArgumentList(arg));
+	      term_Free(arg);
+	      list_Rplaca(scan, subterm);
+	      term_RplacSuperterm(subterm, term1);
+	    }
+	  }
+	  vec_Push((TERM) list_Car(scan));
+	}
+      }
+  }
+  
+  for (scan=VarsForTopLevel; !list_Empty(scan); scan = list_Cdr(scan))
+    list_Rplaca(scan, term_Copy((TERM) list_Car(scan)));
+  if (symbol_Equal(term_TopSymbol(Term), fol_All())) {
+    LIST vars;
+    vars = fol_QuantifierVariables(Term);
+    vars = list_Nconc(vars, list_Copy(VarsForTopLevel));
+    vars = term_DestroyDuplicatesInList(vars);
+    term_RplacArgumentList(term_FirstArgument(Term), vars);
+  }
+  else {
+    TERM newtop;
+    newtop = fol_CreateQuantifier(fol_All(), list_Copy(VarsForTopLevel), list_List(Term));
+    term_RplacSuperterm(Term, newtop);
+    Term = newtop;
+  }
+  vec_SetMax(bottom);
+  return Term;
+}
+
+
+static TERM cnf_RemoveImplFromFormulaPath(TERM Term, TERM PredicateTerm)
+/**********************************************************
+  INPUT:   A term and a predicate term which is a subterm of term
+  RETURNS: The term where implications along the path to PredicateTerm 
+           are replaced.
+  CAUTION: The term is destructively changed.
+           This works only if the superterm member of Term and its 
+	   subterms are set.
+********************************************************/
+{
+  TERM term1;
+  LIST scan;
+  int  bottom;
+  
+  bottom = vec_ActMax();
+  vec_Push(Term);
+  
+  while (bottom != vec_ActMax()) {
+    term1 = (TERM)vec_PopResult();
+    if (term_HasProperSuperterm(PredicateTerm, term1)) {
+      if (symbol_Equal(term_TopSymbol(term1),fol_Implies())) {
+	TERM newterm;
+	term_RplacTop(term1, fol_Or());
+	newterm = term_CreateAddFather(fol_Not(), list_List(list_Car(term_ArgumentList(term1))));
+	list_Rplaca(term_ArgumentList(term1), newterm);
+	term_RplacSuperterm(newterm, term1);
+      }
+      
+      if (!list_Empty(term_ArgumentList(term1)))
+	for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan))
+	  vec_Push(list_Car(scan));
+    }
+  }
+  vec_SetMax(bottom);
+  return Term;
+}
+
+
+static SYMBOL cnf_GetDualSymbol(SYMBOL symbol)
+/********************************************************
+  INPUT:   A predefined symbol.
+  RETURNS: The dual symbol.
+********************************************************/
+{
+  SYMBOL dual;
+
+  dual = symbol;
+  if (symbol_Equal(symbol,fol_All()))
+    dual = fol_Exist();
+  else
+    if (symbol_Equal(symbol,fol_Exist()))
+      dual = fol_All();
+    else
+      if (symbol_Equal(symbol,fol_Or()))
+	dual = fol_And();
+      else
+	if (symbol_Equal(symbol,fol_And()))
+	  dual =  fol_Or();
+  return dual;
+}
+
+
+TERM cnf_NegationNormalFormula(TERM term)
+/********************************************************
+  INPUT:   A term.
+  RETURNS: The negation normal form of the term.
+  CAUTION: The term is destructively changed.
+********************************************************/
+{
+  TERM   term1,subterm,termL;
+  LIST   scan;
+  SYMBOL symbol;
+  int    bottom;
+  
+  bottom = vec_ActMax();
+  vec_Push(term);
+
+  while (bottom != vec_ActMax()) {
+    term1 = (TERM)vec_PopResult();
+    if (symbol_Equal(term_TopSymbol(term1),fol_Not())) {	    
+      subterm = (TERM)list_Car(term_ArgumentList(term1));
+      if (symbol_Equal(term_TopSymbol(subterm),fol_Not())) {
+	term_RplacTop(term1,term_TopSymbol(term_FirstArgument(subterm)));
+	list_Delete(term_ArgumentList(term1));
+	term_RplacArgumentList(term1,term_ArgumentList(term_FirstArgument(subterm)));
+	term_Free(term_FirstArgument(subterm));
+	list_Delete(term_ArgumentList(subterm));
+	term_Free(subterm);
+	vec_Push(term1);
+      }else 
+	if (fol_IsQuantifier(term_TopSymbol(subterm))) {
+	  symbol = (SYMBOL)cnf_GetDualSymbol(term_TopSymbol(subterm));
+	  termL  = term_Create(fol_Not(),
+			       list_List(term_SecondArgument(subterm)));
+	  list_RplacSecond(term_ArgumentList(subterm), termL);
+	  term_RplacTop(term1,symbol);
+	  list_Delete(term_ArgumentList(term1));
+	  term_RplacArgumentList(term1,term_CopyTermList(term_ArgumentList(subterm)));
+	  term_Delete(subterm);
+	} else
+	  if (symbol_Equal(term_TopSymbol(subterm),fol_Or()) || 
+	      symbol_Equal(term_TopSymbol(subterm),fol_And())) {
+	    symbol = (SYMBOL)cnf_GetDualSymbol(term_TopSymbol(subterm));
+	    for (scan = term_ArgumentList(subterm);
+		 !list_Empty(scan);
+		 scan = list_Cdr(scan)) {
+	      termL = (TERM)list_Car(scan);
+	      list_Rplaca(scan, term_Create(fol_Not(),list_List(termL)));
+	    }
+	    term_RplacTop(term1,symbol);
+	    list_Delete(term_ArgumentList(term1));
+	    term_RplacArgumentList(term1,term_CopyTermList(term_ArgumentList(subterm)));
+	    term_Delete(subterm); 
+	  }
+    }
+    if (!list_Empty(term_ArgumentList(term1)))
+      for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan))
+	vec_Push(list_Car(scan));
+  }
+  vec_SetMax(bottom);
+  return term;
+}
+
+
+static TERM cnf_QuantMakeOneVar(TERM term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: The term where all quantifiers quantify over only one variable.
+  CAUTION: The term is destructively changed.
+***************************************************************/
+{
+  TERM   term1,termL;
+  SYMBOL quantor;
+  LIST   scan,varlist;
+  int    bottom;
+  
+  bottom = vec_ActMax();
+  vec_Push(term);       
+
+  while (bottom != vec_ActMax()) {
+    term1 = (TERM)vec_PopResult();
+    if (fol_IsQuantifier(term_TopSymbol(term1))) {
+      quantor = term_TopSymbol(term1);
+      if (list_Length(term_ArgumentList(term_FirstArgument(term1))) > 1) {
+	varlist =
+	  list_Copy(list_Cdr(term_ArgumentList(term_FirstArgument(term1))));
+	for (scan=varlist;!list_Empty(scan);scan=list_Cdr(scan)) {
+	  termL = term_SecondArgument(term1);
+	  term_RplacSecondArgument(term1, fol_CreateQuantifier(quantor,list_List(list_Car(scan)),list_List(termL)));
+	}
+	for (scan=varlist;!list_Empty(scan);scan=list_Cdr(scan)) {
+	  term_RplacArgumentList(term_FirstArgument(term1), 
+				 list_PointerDeleteElement(term_ArgumentList(term_FirstArgument(term1)),list_Car(scan)));
+	}
+	list_Delete(varlist);
+      }
+    }
+    if (!list_Empty(term_ArgumentList(term1)))
+      for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan))
+	vec_Push(list_Car(scan));
+  }
+  vec_SetMax(bottom);
+  return term;
+}
+
+
+static LIST cnf_GetSymbolList(LIST varlist)
+/**************************************************************
+  INPUT:   A list of variables
+  RETURNS: The list of the symbols of the variables.
+***************************************************************/
+{
+  LIST scan,result;
+
+  result = list_Nil();
+  for (scan=varlist;!list_Empty(scan);scan=list_Cdr(scan))
+    result = list_Cons((POINTER)term_TopSymbol((TERM)list_Car(scan)),result);
+
+  return result;
+}
+
+
+static BOOL cnf_TopIsAnd(LIST termlist)
+/**************************************************************
+  INPUT:   A list of terms.
+  RETURNS: True if one term in termlist is a conjunction.
+***************************************************************/
+{
+  LIST scan;
+
+  for (scan=termlist;!list_Empty(scan);scan=list_Cdr(scan))
+    if (term_TopSymbol(list_Car(scan)) == fol_And())
+      return TRUE;
+  return FALSE;
+}
+
+
+static TERM cnf_MakeOneOr(TERM term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: Takes all arguments of an or together.
+  CAUTION: The term is destructively changed.
+***************************************************************/
+{
+
+  LIST   scan;
+
+  if (symbol_Equal(term_TopSymbol(term),fol_Or())) {
+    TERM   argterm;
+    scan=term_ArgumentList(term);
+    while (!list_Empty(scan)) {
+      argterm = (TERM)list_Car(scan);
+      cnf_MakeOneOr(argterm);
+      if (symbol_Equal(term_TopSymbol(argterm),fol_Or())) {
+	scan = list_Cdr(scan);
+	term_RplacArgumentList(term,
+			       list_Nconc(term_ArgumentList(argterm),list_PointerDeleteElement(term_ArgumentList(term),argterm)));
+	term_Free(argterm);
+      }
+      else
+	scan = list_Cdr(scan);
+    }
+  } else if (!symbol_IsPredicate(term_TopSymbol(term)))
+    for (scan=term_ArgumentList(term);!list_Empty(scan);scan=list_Cdr(scan))
+      cnf_MakeOneOr(list_Car(scan));
+  
+  return term;
+}
+
+
+static TERM cnf_MakeOneOrPredicate(TERM term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: Takes all predicates and negated predicates as arguments 
+           of an or together.
+  CAUTION: The term is destructively changed.
+***************************************************************/
+{
+
+  LIST   scan,scan1,predlist;
+
+  if (cnf_TopIsAnd(term_ArgumentList(term))) {
+    
+    for (scan1=term_ArgumentList(term);
+	 !(list_Empty(scan1) || symbol_Equal(term_TopSymbol(list_Car(scan1)),fol_And()));
+	 scan1=list_Cdr(scan1));
+
+    if (!list_Empty(scan1)) {
+      predlist = list_Nil();
+      for (scan=scan1; !list_Empty(scan); scan=list_Cdr(scan)) {
+	if (symbol_IsPredicate(term_TopSymbol(list_Car(scan))) ||
+	    fol_IsNegativeLiteral(list_Car(scan))) {
+	  predlist = list_Cons(list_Car(scan),predlist);
+	}
+      }
+      for (scan=predlist;!list_Empty(scan);scan=list_Cdr(scan))
+	term_RplacArgumentList(term,
+			       list_PointerDeleteElement(term_ArgumentList(term),list_Car(scan)));
+      
+      if (!list_Empty(predlist))
+	term_RplacArgumentList(term, list_Nconc(predlist,term_ArgumentList(term)));
+    }
+  }
+  return term;
+}
+
+
+static TERM cnf_MakeOneOrTerm(TERM term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: Takes all predicates as arguments of an or together.
+  CAUTION: The term is destructively changed.
+***************************************************************/
+{
+  return cnf_MakeOneOrPredicate(cnf_MakeOneOr(term));
+}
+
+
+static TERM cnf_MakeOneAnd(TERM term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: Takes all arguments of an and together.
+  CAUTION: The term is destructively changed.
+***************************************************************/
+{
+  LIST   scan;
+
+  if (symbol_Equal(term_TopSymbol(term),fol_And())) {
+    TERM   argterm;
+    scan=term_ArgumentList(term);
+    while (!list_Empty(scan)) {
+      argterm = (TERM)list_Car(scan);
+      cnf_MakeOneAnd(argterm);
+      if (symbol_Equal(term_TopSymbol(argterm),fol_And())) {
+	scan = list_Cdr(scan);
+	term_RplacArgumentList(term,
+			       list_Nconc(term_ArgumentList(argterm),list_PointerDeleteElement(term_ArgumentList(term),argterm)));
+	term_Free(argterm);
+      }
+      else
+	scan = list_Cdr(scan);
+    }
+  } else if (!symbol_IsPredicate(term_TopSymbol(term)))
+    for (scan=term_ArgumentList(term);!list_Empty(scan);scan=list_Cdr(scan))
+      cnf_MakeOneAnd(list_Car(scan));
+
+  return term;
+}
+
+
+static TERM cnf_MakeOneAndPredicate(TERM term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: Takes all predicates as arguments of one or together.
+  CAUTION: The term is destructively changed.
+***************************************************************/
+{
+  LIST   scan,scan1,predlist;
+  
+  for (scan1=term_ArgumentList(term);
+       !(list_Empty(scan1) || symbol_Equal(term_TopSymbol(list_Car(scan1)),fol_Or()));
+       scan1=list_Cdr(scan1));
+  
+  if (!list_Empty(scan1)) {
+    /* The car of scan1 points to a term with topsymbol 'or' */
+    predlist = list_Nil();
+    for (scan=scan1; !list_Empty(scan); scan=list_Cdr(scan)) {
+      if (symbol_IsPredicate(term_TopSymbol(list_Car(scan))) &&
+	  fol_IsNegativeLiteral(list_Car(scan))) {
+	predlist = list_Cons(list_Car(scan),predlist);
+      }
+    }
+    for (scan=predlist; !list_Empty(scan); scan=list_Cdr(scan))
+      term_RplacArgumentList(term, list_PointerDeleteElement(term_ArgumentList(term),list_Car(scan)));
+    
+    if (!list_Empty(predlist))
+      term_RplacArgumentList(term, list_Nconc(predlist,term_ArgumentList(term)));
+  }
+  return term;
+}
+
+
+static TERM cnf_MakeOneAndTerm(TERM term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: Takes all predicates as arguments of an or together.
+  CAUTION: The term is destructively changed.
+***************************************************************/
+{
+  return cnf_MakeOneAndPredicate(cnf_MakeOneAnd(term));
+}
+
+
+LIST cnf_ComputeLiteralLists(TERM Term)
+/**********************************************************
+  INPUT:   A term in negation normal form without quantifiers.
+  RETURNS: The list of all literal lists corresponding to the
+           CNF of Term.
+***********************************************************/
+{
+  LIST   Scan, Scan1, Scan2, Help, Result, List1, List2, NewResult;
+  SYMBOL Symbol;
+
+  Symbol = term_TopSymbol(Term);
+  Result = list_Nil();
+
+  if (symbol_Equal(Symbol,fol_Or())) {
+    Result = cnf_ComputeLiteralLists(list_Car(term_ArgumentList(Term)));
+    for (Scan=list_Cdr(term_ArgumentList(Term));!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+      Help      = cnf_ComputeLiteralLists(list_Car(Scan));
+      NewResult = list_Nil();
+      for (Scan1=Help;!list_Empty(Scan1);Scan1=list_Cdr(Scan1))	    
+	for (Scan2=Result;!list_Empty(Scan2);Scan2=list_Cdr(Scan2)) {
+	  List1 = list_Car(Scan1);
+	  List2 = list_Car(Scan2);
+	  if (!list_Empty(list_Cdr(Scan2)))
+	    List1 = term_CopyTermList(List1);
+	  if (!list_Empty(list_Cdr(Scan1))) 
+	    List2 = term_CopyTermList(List2);
+	  NewResult = list_Cons(term_DestroyDuplicatesInList(list_Nconc(List1,List2)),
+				NewResult);
+	}
+      list_Delete(Help);
+      list_Delete(Result);
+      Result = NewResult;
+    }
+    return Result;
+  }
+
+  if (symbol_Equal(Symbol,fol_And())) {
+    Result = cnf_ComputeLiteralLists(list_Car(term_ArgumentList(Term)));
+    for (Scan=list_Cdr(term_ArgumentList(Term));!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+      Result = list_Nconc(cnf_ComputeLiteralLists(list_Car(Scan)), Result);
+    }
+    return Result;
+  }
+  
+  if (symbol_Equal(Symbol,fol_Not()) || symbol_IsPredicate(Symbol))
+    return list_List(list_List(term_Copy(Term)));
+  
+    
+  misc_StartErrorReport();
+  misc_ErrorReport("\n In cnf_ComputeLiteralLists: Unexpected junctor in input Formula!\n");
+  misc_FinishErrorReport();
+
+  return Result;
+}
+
+
+static TERM cnf_DistributiveFormula(TERM Formula)
+/**************************************************************
+  INPUT:   A Formula in NNF which consists only of disjunctions and
+           conjunctions.
+  RETURNS: The Formula where the distributivity rule is exhaustively applied
+           and all disjunctions and the top level conjunction are grouped.
+  CAUTION: The Formula is destructively changed.
+***************************************************************/
+{
+  TERM Result;
+  LIST Scan, Lists;
+
+  Lists = cnf_ComputeLiteralLists(Formula);
+  
+  for (Scan= Lists; !list_Empty(Scan); Scan=list_Cdr(Scan))
+    list_Rplaca(Scan,term_Create(fol_Or(), list_Car(Scan)));
+
+  Result = term_Create(fol_And(), Lists);
+  term_Delete(Formula);
+
+  return Result;
+}
+
+
+
+void cnf_FPrintClause(TERM term, FILE* file)
+/**************************************************************
+  INPUT:   A term and a file pointer.
+  RETURNS: Nothing.
+  EFFECT:  Print the term which contains only disjunctions to file.
+           The disjunctions represent a clause.
+***************************************************************/
+{
+    
+  TERM   term1;
+  LIST   scan;
+  int    bottom;
+  
+  bottom = vec_ActMax();
+  vec_Push(term);       
+
+  while (bottom != vec_ActMax()) {
+    term1 = (TERM)vec_PopResult();
+    if (symbol_Equal(term_TopSymbol(term1),fol_Or())) {
+      for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan))
+	vec_Push(list_Car(scan));
+    }else
+      term_FPrint(file,term1);
+  }
+  fputs(".\n", file);
+  vec_SetMax(bottom);
+}
+
+
+void cnf_FPrint(TERM term, FILE* file)
+/**************************************************************
+  INPUT:   A term and a file pointer.
+  RETURNS: Nothing.
+  EFFECT:  Print the term (in negation normal form)
+           which contains only conjunctions of 
+	   disjunctions to file. The conjunctions are interpreted 
+	   to represent different clauses.
+***************************************************************/
+{
+  TERM   term1;
+  LIST   scan;
+  int    bottom;
+  
+  bottom = vec_ActMax();
+  vec_Push(term);       
+
+  while (bottom != vec_ActMax()) {
+    term1 = (TERM)vec_PopResult();
+    if (symbol_Equal(term_TopSymbol(term1),fol_And())) {
+      for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan))
+	vec_Push(list_Car(scan));
+    }else
+      if (symbol_Equal(term_TopSymbol(term1),fol_Or()) ||
+	  symbol_IsPredicate(term_TopSymbol(term1)) ||
+	  symbol_Equal(term_TopSymbol(term1),fol_Not()))
+	cnf_FPrintClause(term1,file);
+  }
+  vec_SetMax(bottom);
+}
+
+
+void cnf_StdoutPrint(TERM term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: Nothing.
+  EFFECT:  Print the term (in negation normal form)
+           which contains only conjunctions of 
+	   disjunctions to standard out. The conjunctions are interpreted 
+	   to represent different clauses.
+***************************************************************/
+{
+  LIST termlist,scan,scan1;
+
+  for (scan=term_ArgumentList(term); !list_Empty(scan); scan=list_Cdr(scan)) {
+    termlist = list_Nil();
+    if (!(symbol_IsPredicate(term_TopSymbol(list_Car(scan))) ||
+	  fol_IsNegativeLiteral(list_Car(scan))))
+      termlist = term_ArgumentList(list_Car(scan));
+    
+    if (!list_Empty(termlist)) {
+      for (scan1=termlist;!list_Empty(scan1);scan1=list_Cdr(scan1))
+	term_Print(list_Car(scan1));
+      puts(".");
+    }else{
+      term_Print(list_Car(scan));
+      puts(".");
+    }
+  }
+}
+
+
+void cnf_FilePrint(TERM term, FILE* file)
+/**************************************************************
+  INPUT:   A term and a file.
+  RETURNS: Nothing.
+  EFFECT:  Print the term (in negation normal form)
+           which contains only conjunctions of 
+	   disjunctions to file. The conjunctions are interpreted 
+	   to represent different clauses.
+***************************************************************/
+{
+  LIST termlist,scan,scan1;
+
+  for (scan=term_ArgumentList(term); !list_Empty(scan); scan=list_Cdr(scan)) {
+    termlist = list_Nil();
+    if (!(symbol_IsPredicate(term_TopSymbol(list_Car(scan))) ||
+	  fol_IsNegativeLiteral(list_Car(scan))))
+      termlist = term_ArgumentList(list_Car(scan));
+    
+    if (!list_Empty(termlist)) {
+      for (scan1=termlist;!list_Empty(scan1);scan1=list_Cdr(scan1))
+	term_FPrint(file,list_Car(scan1));
+      fputs(".\n", file);
+    }else{
+      term_FPrint(file,list_Car(scan));
+      fputs(".\n", file);
+    }
+  }
+  
+}
+
+
+void cnf_FilePrintPrefix(TERM term, FILE* file)
+/**************************************************************
+  INPUT:   A term and a file pointer.
+  RETURNS: Nothing.
+  EFFECT:  Prefix Print the term (in negation normal form)
+           which contains only conjunctions of 
+	   disjunctions to file. The conjunctions are interpreted 
+	   to represent different clauses.
+***************************************************************/
+{
+  LIST termlist,scan,scan1;
+
+  for (scan=term_ArgumentList(term);!list_Empty(scan);scan=list_Cdr(scan)) {
+    termlist = list_Nil();
+    if (!(symbol_IsPredicate(term_TopSymbol(list_Car(scan))) ||
+	  fol_IsNegativeLiteral(list_Car(scan))))
+      termlist = term_ArgumentList(list_Car(scan));
+    
+    if (!list_Empty(termlist)) {
+      for (scan1=termlist;!list_Empty(scan1);scan1=list_Cdr(scan1)) {
+	term_FPrintPrefix(file,list_Car(scan1));
+	if (!list_Empty(list_Cdr(scan1)))
+	  fputs(" | ", file);
+      }
+      fputs(".\n", file);
+    } else {
+      term_FPrintPrefix(file,list_Car(scan));
+      fputs(".\n", file);
+    }
+  }
+}
+
+
+static LIST cnf_SubsumeClauseList(LIST clauselist)
+/**********************************************************
+  INPUT:   A list of clauses.
+  RETURNS: The list of clauses without subsumed clauses.
+  CAUTION: The list is destructively changed.
+***********************************************************/
+{
+  LIST     scan,result;
+  st_INDEX stindex;
+  CLAUSE   actclause;
+
+  stindex = st_IndexCreate();
+  result  = list_Nil();
+
+  for (scan = clauselist; !list_Empty(scan); scan=list_Cdr(scan))
+    res_InsertClauseIndex(list_Car(scan),stindex);
+
+  for (scan=clauselist; !list_Empty(scan); scan=list_Cdr(scan)) {
+    actclause     = list_Car(scan);
+    res_DeleteClauseIndex(actclause,stindex);
+    if (!res_BackSubWithLength(actclause,stindex)) {
+      res_InsertClauseIndex(actclause,stindex);
+      result = list_Cons(actclause,result);
+    }
+  }
+  if (list_Length(result) != list_Length(clauselist)) {
+    for (scan = result; !list_Empty(scan); scan=list_Cdr(scan))
+      clauselist = list_PointerDeleteElement(clauselist,list_Car(scan));
+    if (!list_Empty(result))
+      clause_DeleteClauseList(clauselist);
+  }else
+    list_Delete(clauselist);
+  st_IndexDelete(stindex);
+  return result;
+}
+
+
+static LIST cnf_MakeClauseList(TERM term, BOOL Sorts, BOOL Conclause,
+			       FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A term in cnf and two boolean values indicating
+           whether sorts should be generated and whether the
+	   generated clauses are Conclauses, a flag store and
+	   a precedence.
+  RETURNS: A list of clauses with respect to term. The terms 
+           in the new clauses are the copied subterms from term.
+  EFFECT:  The flag store and the precedence are not changed,
+           but they're needed for creating clauses.
+***************************************************************/
+{
+  LIST   termlist,scan,clauselist,newclauselist,delclauselist,condlist;
+  CLAUSE clause;
+  int    j;
+
+  termlist   = list_Nil();
+  clauselist = list_Nil();
+
+  if (fol_IsTrue(term))
+    return  clauselist;
+
+  if (fol_IsNegativeLiteral(term) || symbol_IsPredicate(term_TopSymbol(term))) {
+    termlist = list_List(term_Copy(term));
+    clause = clause_CreateFromLiterals(termlist, Sorts, Conclause,TRUE,
+				       Flags, Precedence);
+    clauselist = list_Nconc(clauselist,list_List(clause));
+    term_StartMinRenaming();
+    term_Rename(clause_GetLiteralTerm(clause,0));
+    list_Delete(termlist);
+    return clauselist;
+  }
+
+  delclauselist = list_Nil();
+  term          = cnf_MakeOneAndTerm(term);
+  if (symbol_Equal(term_TopSymbol(term), fol_And())) {
+    for (scan=term_ArgumentList(term); !list_Empty(scan); scan=list_Cdr(scan)) {
+      list_Rplaca(scan, cnf_MakeOneOrTerm(list_Car(scan)));
+      termlist = list_Nil();
+      if (!(symbol_IsPredicate(term_TopSymbol(list_Car(scan))) ||
+	    fol_IsNegativeLiteral(list_Car(scan)))) {
+	termlist = term_CopyTermList(term_ArgumentList(list_Car(scan)));
+	termlist = term_DestroyDuplicatesInList(termlist);
+      } else
+	termlist = list_List(term_Copy(list_Car(scan)));
+  
+      if (!list_Empty(termlist)) {
+	clause = clause_CreateFromLiterals(termlist, Sorts, Conclause, TRUE,
+					   Flags, Precedence);
+	term_StartMinRenaming();
+	for (j = 0; j < clause_Length(clause); j++)
+	  term_Rename(clause_GetLiteralTerm(clause,j));
+	clauselist = list_Cons(clause,clauselist);
+	list_Delete(termlist);
+      }
+    }
+  } else {
+    /* Here the term is a disjunction, i.e. there is only one clause */
+    term = cnf_MakeOneOrTerm(term);
+    if (!(symbol_IsPredicate(term_TopSymbol(term)) ||
+	  fol_IsNegativeLiteral(term))) {
+      termlist = term_CopyTermList(term_ArgumentList(term));
+      termlist = term_DestroyDuplicatesInList(termlist);
+    } else
+      termlist = list_List(term_Copy(term));
+    
+    if (!list_Empty(termlist)) {
+      clause = clause_CreateFromLiterals(termlist, Sorts, Conclause, TRUE,
+					 Flags, Precedence);
+      term_StartMinRenaming();
+      for (j = 0; j < clause_Length(clause); j++)
+	term_Rename(clause_GetLiteralTerm(clause,j));
+      clauselist = list_Cons(clause,clauselist);
+      list_Delete(termlist);
+    }
+  }
+
+  for (scan=clauselist; !list_Empty(scan); scan=list_Cdr(scan)) {
+    condlist = cond_CondFast(list_Car(scan));
+    if (!list_Empty(condlist))
+      clause_DeleteLiterals(list_Car(scan), condlist, Flags, Precedence);
+    list_Delete(condlist);
+  }
+  clauselist    = cnf_SubsumeClauseList(clauselist);
+  newclauselist = list_Nil();
+  while (!list_Empty(clauselist)) {
+    clause = res_SelectLightestClause(clauselist);
+    newclauselist = list_Nconc(newclauselist,list_List(clause));
+    clauselist = list_PointerDeleteElement(clauselist,clause);
+  }
+  list_Delete(clauselist);
+  for (scan=newclauselist; !list_Empty(scan); scan=list_Cdr(scan)) {
+    if (res_HasTautology(list_Car(scan)))
+      delclauselist = list_Cons(list_Car(scan),delclauselist);
+  }
+  for (scan=delclauselist; !list_Empty(scan); scan=list_Cdr(scan))
+    newclauselist = list_PointerDeleteElement(newclauselist,list_Car(scan));
+  clause_DeleteClauseList(delclauselist);
+    
+  return newclauselist;
+}
+
+
+TERM cnf_Flatten(TERM Term, SYMBOL Symbol)
+/**************************************************************
+  INPUT:   A <Term> and <Symbol> that is assumed to be associative.
+  RETURNS: If the top symbol of <Term> is <Symbol> the <Term> is flattened
+           as long as it contains further direct subterms starting with <Symbol>
+  CAUTION: The term is destructively changed.
+***************************************************************/
+{
+  LIST   Scan1,Scan2;
+
+  if (symbol_Equal(term_TopSymbol(Term), Symbol)) {
+    TERM   Argterm;
+    Scan1 =term_ArgumentList(Term);
+    while (!list_Empty(Scan1)) {
+      Argterm = (TERM)list_Car(Scan1);
+      Scan2   = list_Cdr(Scan1);
+      if (symbol_Equal(term_TopSymbol(Argterm),Symbol)) {
+	cnf_Flatten(Argterm,Symbol);
+	list_NInsert(Scan1,list_Cdr(term_ArgumentList(Argterm)));   /* Be efficient ... */
+	list_Rplaca(Scan1,list_Car(term_ArgumentList(Argterm)));
+	list_Free(term_ArgumentList(Argterm));
+	term_Free(Argterm);
+      }
+      Scan1  = Scan2;
+    }
+  }
+  return Term;
+}
+
+
+static TERM cnf_FlattenPath(TERM Term, TERM PredicateTerm)
+/**************************************************************
+  INPUT:   A <Term> and <Symbol> that is assumed to be associative,
+           and a predicate term which is a subterm of term
+  RETURNS: If the top symbol of <Term> is <Symbol> the <Term> is flattened
+           as long as it contains further direct subterms starting with <Symbol>
+  CAUTION: The term is destructively changed.
+***************************************************************/
+{
+  TERM   subterm;
+  
+  subterm = Term;
+  while (symbol_Equal(term_TopSymbol(subterm), fol_All()))
+    subterm = term_SecondArgument(subterm);
+
+  if (symbol_Equal(term_TopSymbol(subterm), fol_Or())) {
+    TERM Argterm;
+    LIST scan1;
+    scan1 = term_ArgumentList(subterm);
+    while (!list_Empty(scan1)) {
+      LIST scan2;
+      Argterm = (TERM)list_Car(scan1);
+      scan2   = list_Cdr(scan1);
+      if (term_HasProperSuperterm(PredicateTerm, Argterm)) {
+	if (symbol_Equal(term_TopSymbol(Argterm),fol_Or())) {
+	  LIST l;
+	  cnf_Flatten(Argterm,fol_Or());
+	  for (l=term_ArgumentList(Argterm); !list_Empty(l); l=list_Cdr(l))
+	    term_RplacSuperterm((TERM) list_Car(l), subterm);
+	  list_NInsert(scan1,list_Cdr(term_ArgumentList(Argterm)));   /* Be efficient ... */
+	  list_Rplaca(scan1,list_Car(term_ArgumentList(Argterm)));
+	  list_Free(term_ArgumentList(Argterm));
+	  term_Free(Argterm);
+	}
+      }
+      scan1  = scan2;
+    }
+  }
+  return Term;
+}
+
+
+static void cnf_DistrQuantorNoVarSub(TERM Term)
+/**************************************************************
+  INPUT:   A formula in negation normal form starting with a universal 
+           (existential) quantifier and a disjunction (conjunction) as argument.
+  EFFECT:  The Quantor is distributed if possible.
+  CAUTION: The term is destructively changed.
+***************************************************************/
+{
+  LIST   Variables,Subformulas,Scan1,Scan2,Rest;
+  TERM   Subterm,Var,NewForm;
+  SYMBOL Subtop,Top;
+
+  Top       = term_TopSymbol(Term);
+  Variables = list_Copy(fol_QuantifierVariables(Term));
+  Subterm   = term_SecondArgument(Term);
+  Subtop    = term_TopSymbol(Subterm);
+  Subterm   = cnf_Flatten(Subterm,Subtop);
+
+  for (Scan1=Variables;!list_Empty(Scan1);Scan1=list_Cdr(Scan1)) {
+    Subformulas = list_Nil();
+    Var         = (TERM)list_Car(Scan1);
+    for (Scan2=term_ArgumentList(Subterm);!list_Empty(Scan2);Scan2=list_Cdr(Scan2))
+      if (!fol_VarOccursFreely(Var,list_Car(Scan2)))
+	Subformulas = list_Cons(list_Car(Scan2),Subformulas);
+    if (!list_Empty(Subformulas)) {
+      Rest     = list_NPointerDifference(term_ArgumentList(Subterm),Subformulas);
+      if (list_Empty(list_Cdr(Rest))) { /* One subformula */
+	if (symbol_Equal(Top,term_TopSymbol(list_Car(Rest)))) { /* Optimization: quantifier still exist */
+	  NewForm = (TERM)list_Car(Rest);
+	  term_RplacArgumentList(term_FirstArgument(NewForm),
+				 list_Cons((POINTER)Var,fol_QuantifierVariables(NewForm)));
+	  list_Delete(Rest);
+	}
+	else
+	  NewForm = fol_CreateQuantifier(Top,list_List((POINTER)Var),Rest);
+      }
+      else
+	NewForm = fol_CreateQuantifier(Top,list_List((POINTER)Var),list_List(term_Create(Subtop,Rest)));
+      term_RplacArgumentList(Subterm,list_Cons(NewForm,Subformulas));
+      term_RplacArgumentList(term_FirstArgument(Term),
+			     list_PointerDeleteElement(fol_QuantifierVariables(Term),(POINTER)Var));
+    } 
+  }
+
+  if (list_Empty(fol_QuantifierVariables(Term))) { /* All variables moved inside */
+    term_Free(term_FirstArgument(Term));
+    list_Delete(term_ArgumentList(Term));
+    term_RplacTop(Term,Subtop);
+    term_RplacArgumentList(Term,term_ArgumentList(Subterm));
+    term_Free(Subterm);
+  }
+  list_Delete(Variables);
+}
+
+
+static TERM cnf_AntiPrenex(TERM Term)
+/**************************************************************
+  INPUT:   A formula in negation normal form.
+  RETURNS: The term after application of anti-prenexing. Quantifiers
+           are moved inside as long as possible.
+  CAUTION: The term is destructively changed.
+***************************************************************/
+{
+  LIST   Scan;
+  SYMBOL Top;
+
+  Top = term_TopSymbol(Term);
+
+  if (fol_IsQuantifier(Top)) {
+    TERM   Subterm,Actterm;
+    SYMBOL DistrSymb,Subtop;          /* The junctor the respective quantifier distributes over */
+    
+    Subterm = term_SecondArgument(Term);
+    Subtop  = term_TopSymbol(Subterm);
+
+    if (!symbol_IsPredicate(Subtop) && 
+	!symbol_Equal(Subtop,fol_Not())) { /* Formula in NNF: No Literals or Atoms */
+      if (symbol_Equal(Top,fol_All()))
+	DistrSymb = fol_And();
+      else
+	DistrSymb = fol_Or();
+      if (fol_IsQuantifier(Subtop)) {
+	cnf_AntiPrenex(Subterm);
+	Subtop = term_TopSymbol(Subterm);
+      }
+      if (symbol_Equal(Subtop,DistrSymb)) {
+	LIST Variables;	
+	LIST NewVars;
+	Variables = fol_QuantifierVariables(Term);
+	Subterm   = cnf_Flatten(Subterm,DistrSymb);
+	for (Scan=term_ArgumentList(Subterm);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+	  Actterm = (TERM)list_Car(Scan);
+	  NewVars = list_NIntersect(fol_FreeVariables(Actterm),Variables,
+				    (BOOL (*)(POINTER,POINTER))term_Equal);
+	  if (!list_Empty(NewVars)) {
+	    if (symbol_Equal(Top,term_TopSymbol(Actterm))) {        /* Quantor already there */
+	      term_CopyTermsInList(NewVars);
+	      term_RplacArgumentList(term_FirstArgument(Actterm),
+				     list_Nconc(fol_QuantifierVariables(Actterm),
+						NewVars));
+	    }
+	    else {
+	      term_CopyTermsInList(NewVars);
+	      list_Rplaca(Scan,fol_CreateQuantifier(Top, NewVars, list_List(Actterm)));
+	    }
+	  }
+	}
+	term_Delete(term_FirstArgument(Term));   /* Delete old variable list */
+	list_Delete(term_ArgumentList(Term)); 
+	term_RplacTop(Term,DistrSymb);
+	term_RplacArgumentList(Term,term_ArgumentList(Subterm));
+	term_Free(Subterm);
+	for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan)) 
+	  list_Rplaca(Scan,cnf_AntiPrenex(list_Car(Scan)));
+      }
+      else 
+	if (!fol_IsQuantifier(Subtop)) {
+	  cnf_DistrQuantorNoVarSub(Term);
+	  for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+	    cnf_AntiPrenex(list_Car(Scan));
+	}
+    }
+  }
+  else
+    if (!symbol_Equal(Top,fol_Not()) && !symbol_IsPredicate(Top))
+      for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+	cnf_AntiPrenex(list_Car(Scan));
+
+  return Term;
+}
+
+
+static void cnf_DistrQuantorNoVarSubPath(TERM Term, TERM PredicateTerm)
+/**************************************************************
+  INPUT:   A formula in negation normal form starting with a universal 
+           (existential) quantifier and a disjunction (conjunction) as argument
+	   and a predicate term which is a subterm of term.
+  CAUTION: The term is destructively changed.
+***************************************************************/
+{
+  LIST   Variables,Subformulas,Scan1,Scan2,Rest;
+  TERM   Subterm,Var,NewForm;
+  SYMBOL Subtop,Top;
+
+  /*fputs("\nAN0:\t",stdout);term_Print(Term);*/
+
+  Top       = term_TopSymbol(Term);
+  Variables = list_Copy(fol_QuantifierVariables(Term));
+  Subterm   = term_SecondArgument(Term);
+  Subtop    = term_TopSymbol(Subterm);
+  Subterm   = cnf_Flatten(Subterm,Subtop);
+
+  /*fputs("\nAN1:\t",stdout);term_Print(Subterm);*/
+
+  for (Scan1=Variables;!list_Empty(Scan1);Scan1=list_Cdr(Scan1)) {
+    Subformulas = list_Nil();
+    Var         = (TERM)list_Car(Scan1);
+    /* Find subterms in which the variable does not occur freely */
+    for (Scan2=term_ArgumentList(Subterm);!list_Empty(Scan2);Scan2=list_Cdr(Scan2))
+      if (!fol_VarOccursFreely(Var,list_Car(Scan2)))
+	Subformulas = list_Cons(list_Car(Scan2),Subformulas);
+    if (!list_Empty(Subformulas)) {
+      /* Rest is the list of those subterms where the variable does occur freely */
+      Rest     = list_NPointerDifference(term_ArgumentList(Subterm),Subformulas);
+      if (list_Empty(list_Cdr(Rest))) { /* One subformula */
+	if (symbol_Equal(Top,term_TopSymbol(list_Car(Rest)))) { /* Optimization: quantifier still exist */
+	  NewForm = (TERM)list_Car(Rest);
+	  /* Move one variable down */
+	  term_RplacArgumentList(term_FirstArgument(NewForm),
+				 list_Cons((POINTER)Var,fol_QuantifierVariables(NewForm)));
+	  list_Delete(Rest);
+	}
+	else {
+	  NewForm = fol_CreateQuantifierAddFather(Top,list_List((POINTER)Var),
+						  Rest);
+	}
+      }
+      else {
+	TERM t;
+	t = term_CreateAddFather(Subtop,Rest);
+	NewForm = fol_CreateQuantifierAddFather(Top,list_List((POINTER)Var),list_List(t));
+      }
+      if (term_HasProperSuperterm(PredicateTerm, NewForm))
+	NewForm = cnf_AntiPrenexPath(NewForm, PredicateTerm);
+      term_RplacArgumentList(Subterm,list_Cons(NewForm,Subformulas));
+      term_RplacSuperterm(NewForm, Subterm);
+      term_RplacArgumentList(term_FirstArgument(Term),
+			     list_PointerDeleteElement(fol_QuantifierVariables(Term),(POINTER)Var));
+    } 
+  }
+
+  if (list_Empty(fol_QuantifierVariables(Term))) { /* All variables moved inside */
+    LIST l;
+    term_Free(term_FirstArgument(Term));
+    list_Delete(term_ArgumentList(Term));
+    term_RplacTop(Term,Subtop);
+    term_RplacArgumentList(Term,term_ArgumentList(Subterm));
+    term_Free(Subterm);
+    for (l=term_ArgumentList(Term); !list_Empty(l); l=list_Cdr(l))
+      term_RplacSuperterm((TERM) list_Car(l), Term);
+  }
+  list_Delete(Variables);
+}
+
+
+static TERM cnf_AntiPrenexPath(TERM Term, TERM PredicateTerm)
+/**************************************************************
+  INPUT:   A formula in negation normal form and a predicate term
+           which is a subterm of term.
+  RETURNS: The term after application of anti-prenexing. Quantifiers
+           are moved inside along the path as long as possible.
+  CAUTION: The term is destructively changed.
+***************************************************************/
+{
+  LIST   Scan;
+  SYMBOL Top;
+
+  Top = term_TopSymbol(Term);
+
+  if (fol_IsQuantifier(Top)) {
+    TERM   Subterm,Actterm;
+    SYMBOL DistrSymb,Subtop;          /* The junctor the respective quantifier distributes over */
+    
+    Subterm = term_SecondArgument(Term);
+    Subtop  = term_TopSymbol(Subterm);
+
+    if (!symbol_Equal(Subtop,fol_Not()) && !symbol_IsPredicate(Subtop)) { /* No Literals or Atoms */
+      if (symbol_Equal(Top,fol_All()))
+	DistrSymb = fol_And();
+      else
+	DistrSymb = fol_Or();
+      if (fol_IsQuantifier(Subtop)) {
+	cnf_AntiPrenexPath(Subterm, PredicateTerm);
+	Subtop = term_TopSymbol(Subterm);
+      }
+      if (symbol_Equal(Subtop,DistrSymb)) {
+	LIST Variables;	
+	LIST NewVars;
+	Variables = fol_QuantifierVariables(Term);
+	Subterm   = cnf_Flatten(Subterm,DistrSymb);
+	term_AddFatherLinks(Subterm);
+	/*
+	  for (l=term_ArgumentList(Subterm); !list_Empty(l); l=list_Cdr(l))
+	  term_RplacSuperterm((TERM) list_Car(l), Subterm);
+	*/
+	for (Scan=term_ArgumentList(Subterm);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+	  Actterm = (TERM)list_Car(Scan);
+	  NewVars = list_NIntersect(fol_FreeVariables(Actterm),Variables,
+				    (BOOL (*)(POINTER,POINTER))term_Equal);
+	  if (!list_Empty(NewVars)) {
+	    if (symbol_Equal(Top,term_TopSymbol(Actterm))) {         /* Quantor already there */
+	      term_CopyTermsInList(NewVars);
+	      term_RplacArgumentList(term_FirstArgument(Actterm),
+				     list_Nconc(fol_QuantifierVariables(Actterm), NewVars));
+	    }
+	    else {
+	      term_CopyTermsInList(NewVars);
+	      list_Rplaca(Scan,fol_CreateQuantifierAddFather(Top, NewVars, list_List(Actterm)));
+	    }
+	  }
+	}
+	term_Delete(term_FirstArgument(Term));   /* Delete old variable list */
+	list_Delete(term_ArgumentList(Term)); 
+	term_RplacTop(Term,DistrSymb);
+	term_RplacArgumentList(Term,term_ArgumentList(Subterm));
+	term_Free(Subterm);
+	term_AddFatherLinks(Term);
+	for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+	  term_RplacSuperterm((TERM) list_Car(Scan), Term);
+	  if (term_HasPointerSubterm((TERM) list_Car(Scan), PredicateTerm)) {
+	    puts("\ncheck1");
+	    list_Rplaca(Scan,cnf_AntiPrenexPath(list_Car(Scan), PredicateTerm));
+	    term_RplacSuperterm((TERM) list_Car(Scan), Term);
+	  }
+	}
+      }
+      else
+	if (!fol_IsQuantifier(Subtop)) {
+	  cnf_DistrQuantorNoVarSubPath(Term, PredicateTerm);
+	  for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+	    if (term_HasPointerSubterm(list_Car(Scan), PredicateTerm))
+	      cnf_AntiPrenexPath(list_Car(Scan), PredicateTerm);
+	  }
+	}
+    }
+  }
+  else
+    if (!symbol_Equal(Top,fol_Not()) && !symbol_IsPredicate(Top))
+      for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+	if (term_HasProperSuperterm(PredicateTerm, (TERM) list_Car(Scan)))
+	  cnf_AntiPrenexPath(list_Car(Scan), PredicateTerm);
+  
+  term_AddFatherLinks(Term);
+  return Term;
+}
+
+
+static TERM cnf_RemoveTrivialOperators(TERM Term)
+/**************************************************************
+  INPUT:   A formula.
+  RETURNS: The formula after
+           removal of "or" and "and" with only one argument
+  CAUTION: The term is destructively changed.
+***************************************************************/
+{
+  SYMBOL Top;
+  LIST   Scan;
+
+  Top = term_TopSymbol(Term);
+
+  if (symbol_IsPredicate(Top))
+    return Term;
+
+  if ((symbol_Equal(Top,fol_And()) || symbol_Equal(Top,fol_Or())) &&
+      list_Empty(list_Cdr(term_ArgumentList(Term)))) {
+    TERM Result;
+    Result = term_FirstArgument(Term);
+    term_RplacSuperterm(Result, term_Superterm(Term));
+    list_Delete(term_ArgumentList(Term));
+    term_Free(Term);
+    return cnf_RemoveTrivialOperators(Result);
+  }
+
+  for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    list_Rplaca(Scan,cnf_RemoveTrivialOperators(list_Car(Scan)));
+    term_RplacSuperterm((TERM) list_Car(Scan), Term);
+  }
+  
+  return Term;
+}
+
+
+static TERM cnf_SimplifyQuantors(TERM Term)
+  /**************************************************************
+  INPUT:   A formula.
+  RETURNS: The formula after
+	   removal of bindings of variables that don't occur in the
+	   respective subformula and possible mergings of quantors
+  CAUTION: The term is destructively changed.
+***************************************************************/
+{
+  SYMBOL Top;
+  LIST   Scan;
+
+  Top = term_TopSymbol(Term);
+
+  if (symbol_IsPredicate(Top) || symbol_Equal(Top,fol_Varlist()))
+    return Term;
+
+  if (fol_IsQuantifier(Top)) {
+    LIST Vars;
+    TERM Var,Subterm,Aux;
+    Vars    = list_Nil();
+    Subterm = term_SecondArgument(Term);
+
+    while (symbol_Equal(term_TopSymbol(Subterm),Top)) {
+      term_RplacArgumentList(term_FirstArgument(Term),
+			     list_Nconc(fol_QuantifierVariables(Term),fol_QuantifierVariables(Subterm)));
+      term_Free(term_FirstArgument(Subterm));
+      Aux = term_SecondArgument(Subterm);
+      list_Delete(term_ArgumentList(Subterm));
+      term_Free(Subterm);
+      list_Rplaca(list_Cdr(term_ArgumentList(Term)),Aux);
+      Subterm = Aux;
+    }
+    
+    for (Scan=fol_QuantifierVariables(Term);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+      Var = (TERM)list_Car(Scan);
+      if (!fol_VarOccursFreely(Var,Subterm))
+	Vars = list_Cons(Var,Vars);
+    }
+    if (!list_Empty(Vars)) {
+      Subterm = term_FirstArgument(Term);
+      term_RplacArgumentList(Subterm,list_NPointerDifference(term_ArgumentList(Subterm),Vars));
+      term_DeleteTermList(Vars);
+      if (list_Empty(term_ArgumentList(Subterm))) {
+	Subterm = term_SecondArgument(Term);
+	term_Delete(term_FirstArgument(Term));
+	list_Delete(term_ArgumentList(Term));
+	term_Free(Term);
+	return cnf_SimplifyQuantors(Subterm);
+      }
+    }
+  }
+  
+  for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+    list_Rplaca(Scan,cnf_SimplifyQuantors(list_Car(Scan)));
+  
+  return Term; 
+}
+
+
+TERM cnf_RemoveTrivialAtoms(TERM Term)
+/**************************************************************
+  INPUT:   A formula.
+  RETURNS: The formula where occurrences of the atoms "true"
+           and "false" are propagated and eventually removed.
+  CAUTION: The term is destructively changed.
+***************************************************************/
+{
+  SYMBOL Top,Subtop;
+  LIST   Scan;
+  TERM   Result;
+  BOOL   Update;
+
+
+  if (!term_IsComplex(Term))
+    return Term;
+  
+  Top    = term_TopSymbol(Term);
+  Update = FALSE;
+
+  if (symbol_Equal(Top,fol_And())) {
+    Scan  = term_ArgumentList(Term);
+    while (!list_Empty(Scan)) {
+      Result = cnf_RemoveTrivialAtoms(list_Car(Scan));
+      Subtop = term_TopSymbol(Result);
+      if (symbol_Equal(Subtop,fol_True()))
+	Update = TRUE;
+      else
+	if (symbol_Equal(Subtop,fol_False())) {
+	  term_RplacTop(Term,fol_False());
+	  term_DeleteTermList(term_ArgumentList(Term));
+	  term_RplacArgumentList(Term,list_Nil());
+	  return Term;
+	}
+      Scan = list_Cdr(Scan);
+    }
+    if (Update) {
+      term_RplacArgumentList(Term,fol_DeleteTrueTermFromList(term_ArgumentList(Term)));
+      if (list_Empty(term_ArgumentList(Term))) {
+	term_RplacTop(Term,fol_True());
+	return Term;
+      }
+    }
+  }
+  else if (symbol_Equal(Top,fol_Or())) {
+    Scan  = term_ArgumentList(Term);
+    while (!list_Empty(Scan)) {
+      Result = cnf_RemoveTrivialAtoms(list_Car(Scan));
+      Subtop = term_TopSymbol(Result);
+      if (symbol_Equal(Subtop,fol_False()))
+	Update = TRUE;
+      else
+	if (symbol_Equal(Subtop,fol_True())) {
+	  term_RplacTop(Term,fol_True());
+	  term_DeleteTermList(term_ArgumentList(Term));
+	  term_RplacArgumentList(Term,list_Nil());
+	  return Term;
+	}
+      Scan = list_Cdr(Scan);
+    }
+    if (Update) {
+      term_RplacArgumentList(Term,fol_DeleteFalseTermFromList(term_ArgumentList(Term)));
+      if (list_Empty(term_ArgumentList(Term))) {
+	term_RplacTop(Term,fol_False());
+	return Term;
+      }
+    }
+  }
+  else if (fol_IsQuantifier(Top) || symbol_Equal(Top,fol_Not())) {
+    if (fol_IsQuantifier(Top))
+      Result = cnf_RemoveTrivialAtoms(term_SecondArgument(Term));
+    else
+      Result = cnf_RemoveTrivialAtoms(term_FirstArgument(Term));
+    Subtop = term_TopSymbol(Result);
+    if ((symbol_Equal(Subtop,fol_False()) && symbol_Equal(Top,fol_Not())) ||
+	(symbol_Equal(Subtop,fol_True()) && fol_IsQuantifier(Top))) {
+      term_RplacTop(Term,fol_True());
+      term_DeleteTermList(term_ArgumentList(Term));
+      term_RplacArgumentList(Term,list_Nil());
+      return Term;
+    }
+    else
+      if ((symbol_Equal(Subtop,fol_True()) && symbol_Equal(Top,fol_Not())) ||
+	  (symbol_Equal(Subtop,fol_False()) && fol_IsQuantifier(Top))) {
+	term_RplacTop(Term,fol_False());
+	term_DeleteTermList(term_ArgumentList(Term));
+	term_RplacArgumentList(Term,list_Nil());
+	return Term;
+      }
+  }
+  else if (symbol_Equal(Top,fol_Implies())) {
+    Result = cnf_RemoveTrivialAtoms(term_FirstArgument(Term));
+    Subtop = term_TopSymbol(Result);
+    if (symbol_Equal(Subtop,fol_False())) {
+      term_RplacTop(Term,fol_True());
+      term_DeleteTermList(term_ArgumentList(Term));
+      term_RplacArgumentList(Term,list_Nil());
+      return Term;
+    }
+    else if (symbol_Equal(Subtop,fol_True())) {
+      term_Delete(Result);
+      Result = term_SecondArgument(Term);
+      list_Delete(term_ArgumentList(Term));
+      term_RplacTop(Term,term_TopSymbol(Result));
+      term_RplacArgumentList(Term,term_ArgumentList(Result));
+      term_Free(Result);
+      return cnf_RemoveTrivialAtoms(Term);
+    }
+    Result = cnf_RemoveTrivialAtoms(term_SecondArgument(Term));
+    Subtop = term_TopSymbol(Result);
+    if (symbol_Equal(Subtop,fol_True())) {
+      term_RplacTop(Term,fol_True());
+      term_DeleteTermList(term_ArgumentList(Term));
+      term_RplacArgumentList(Term,list_Nil());
+      return Term;
+    }
+    else if (symbol_Equal(Subtop,fol_False())) {
+      term_RplacTop(Term,fol_Not());
+      term_RplacArgumentList(Term,fol_DeleteFalseTermFromList(term_ArgumentList(Term)));
+    }
+  }
+  else if (symbol_Equal(Top,fol_Equiv())) {
+    Result = cnf_RemoveTrivialAtoms(term_FirstArgument(Term));
+    Subtop = term_TopSymbol(Result);
+    if (symbol_Equal(Subtop,fol_False())) {
+      term_RplacTop(Term,fol_Not());
+      term_RplacArgumentList(Term,fol_DeleteFalseTermFromList(term_ArgumentList(Term)));
+      if (list_Empty(term_ArgumentList(Term))) {
+	term_RplacTop(Term, fol_True());
+	return Term;
+      }
+      return cnf_RemoveTrivialAtoms(Term);
+    }
+    else if (symbol_Equal(Subtop,fol_True())) {
+      term_Delete(Result);
+      Result = term_SecondArgument(Term);
+      list_Delete(term_ArgumentList(Term));
+      term_RplacTop(Term,term_TopSymbol(Result));
+      term_RplacArgumentList(Term,term_ArgumentList(Result));
+      term_Free(Result);
+      return cnf_RemoveTrivialAtoms(Term);
+    }
+    Result = cnf_RemoveTrivialAtoms(term_SecondArgument(Term));
+    Subtop = term_TopSymbol(Result);
+    if (symbol_Equal(Subtop,fol_False())) {
+      term_RplacTop(Term,fol_Not());
+      term_RplacArgumentList(Term,fol_DeleteFalseTermFromList(term_ArgumentList(Term)));
+    }
+    else if (symbol_Equal(Subtop,fol_True())) {
+      term_Delete(Result);
+      Result = term_FirstArgument(Term);
+      list_Delete(term_ArgumentList(Term));
+      term_RplacTop(Term,term_TopSymbol(Result));
+      term_RplacArgumentList(Term,term_ArgumentList(Result));
+      term_Free(Result);
+    }
+  }
+
+  return Term;
+}
+
+
+TERM cnf_ObviousSimplifications(TERM Term)
+/**************************************************************
+  INPUT:   A formula.
+  RETURNS: The formula after performing the following simplifications:
+             - remove "or" and "and" with only one argument
+	     - remove bindings of variables that don't occur in the
+	       respective subformula
+	     - merge quantors
+  CAUTION: The term is destructively changed.
+***************************************************************/
+{
+  Term = cnf_RemoveTrivialAtoms(Term);
+  Term = cnf_RemoveTrivialOperators(Term);
+  Term = cnf_SimplifyQuantors(Term);
+
+  return Term;
+}
+
+
+/* EK: warum wird Term zurueckgegeben, wenn er destruktiv geaendert wird??? */
+static TERM cnf_SkolemFormula(TERM Term, PRECEDENCE Precedence, LIST* Symblist)
+/**************************************************************
+  INPUT:   A formula in negation normal form, a precedence and pointer
+           to a list used as return value.
+  RETURNS: The skolemized term and the list of introduced Skolem functions.
+  CAUTION: The term is destructively changed.
+           The precedence of the new Skolem functions is set in <Precedence>.
+***************************************************************/
+{
+  SYMBOL Top,SkolemSymbol;
+  TERM   Subterm,SkolemTerm;
+  LIST   Varlist,Scan;
+  NAT    Arity;
+
+  Top = term_TopSymbol(Term);
+    
+  if (fol_IsQuantifier(term_TopSymbol(Term))) {
+    if (symbol_Equal(Top,fol_All())) {
+      term_Delete(term_FirstArgument(Term));
+      Subterm = term_SecondArgument(Term);
+      list_Delete(term_ArgumentList(Term));
+      term_RplacTop(Term,term_TopSymbol(Subterm));
+      term_RplacArgumentList(Term,term_ArgumentList(Subterm));
+      term_Free(Subterm);
+      return cnf_SkolemFormula(Term, Precedence, Symblist);
+    } 
+    else {  /* exist quantifier */
+      Varlist = fol_FreeVariables(Term);
+      Arity   = list_Length(Varlist);
+      for (Scan=fol_QuantifierVariables(Term);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+	SkolemSymbol = symbol_CreateSkolemFunction(Arity, Precedence);
+	*Symblist  = list_Cons((POINTER)SkolemSymbol, *Symblist);
+	SkolemTerm = term_Create(SkolemSymbol,Varlist); /* Caution: Sharing of Varlist ! */
+	fol_ReplaceVariable(term_SecondArgument(Term),term_TopSymbol(list_Car(Scan)),SkolemTerm);
+	term_Free(SkolemTerm);
+      }
+      list_Delete(Varlist);
+      term_Delete(term_FirstArgument(Term));
+      Subterm = term_SecondArgument(Term);
+      list_Delete(term_ArgumentList(Term));
+      term_RplacTop(Term,term_TopSymbol(Subterm));
+      term_RplacArgumentList(Term,term_ArgumentList(Subterm));
+      term_Free(Subterm);
+      return cnf_SkolemFormula(Term, Precedence, Symblist);
+    } 
+  }
+  else
+    if (symbol_Equal(Top,fol_And()) || symbol_Equal(Top,fol_Or()))
+      for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+	cnf_SkolemFormula(list_Car(Scan), Precedence, Symblist);
+  return Term;
+}
+
+
+static TERM cnf_Cnf(TERM Term, PRECEDENCE Precedence, LIST* Symblist)
+/**************************************************************
+  INPUT:   A formula, a precedence and a pointer to a list of symbols
+           used as return value.
+  RETURNS: The term is transformed to conjunctive normal form.
+  EFFECT:  The term is destructively changed and not normalized.
+           The precedence of new Skolem symbols is set in <Precedence>.
+***************************************************************/
+{
+  /* Necessary because ren_Rename crashes if a e.g. and() has only one argument */
+  Term = cnf_ObviousSimplifications(Term);
+  term_AddFatherLinks(Term);
+  Term = ren_Rename(Term, Precedence, Symblist, FALSE, FALSE);
+  Term = cnf_RemoveEquivImplFromFormula(Term);
+  Term = cnf_NegationNormalFormula(Term);
+  Term = cnf_SkolemFormula(cnf_AntiPrenex(Term), Precedence, Symblist);
+  Term = cnf_DistributiveFormula(Term);
+
+  return Term;
+}
+
+
+static LIST cnf_GetUsedTerms(CLAUSE C, PROOFSEARCH Search,
+			     HASH InputClauseToTermLabellist) 
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+***************************************************************/
+{
+  LIST UsedTerms, Used2, Scan;
+  UsedTerms = list_Copy(hsh_Get(InputClauseToTermLabellist, C));
+  UsedTerms = cnf_DeleteDuplicateLabelsFromList(UsedTerms);
+  if (!list_Empty(UsedTerms))
+    return UsedTerms;
+
+  for (Scan = clause_ParentClauses(C); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    CLAUSE P;
+    int ClauseNumber;
+    ClauseNumber = (int) list_Car(Scan);
+    P = clause_GetNumberedCl(ClauseNumber, prfs_WorkedOffClauses(Search));
+    if (P == NULL) {
+      P = clause_GetNumberedCl(ClauseNumber, prfs_UsableClauses(Search));
+      if (P == NULL)
+	P = clause_GetNumberedCl(ClauseNumber, prfs_DocProofClauses(Search));
+    }
+    Used2 = cnf_GetUsedTerms(P, Search, InputClauseToTermLabellist);
+    UsedTerms = list_Nconc(UsedTerms, Used2);
+  }
+  return UsedTerms;
+}
+
+
+static BOOL cnf_HaveProofOptSkolem(PROOFSEARCH Search, TERM topterm,
+				   char* toplabel, TERM term2,
+				   LIST* UsedTerms, LIST* Symblist,
+				   HASH InputClauseToTermLabellist)
+/**************************************************************
+  INPUT:   
+  RETURNS: ??? EK
+***************************************************************/
+{
+  LIST       ConClauses, EmptyClauses;
+  LIST       scan;
+  BOOL       found;
+  LIST       Usables;
+  FLAGSTORE  Flags;
+  PRECEDENCE Precedence;
+
+  Flags      = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+  ConClauses = list_Nil();
+  found      = FALSE;
+  /* List of clauses from term2 */
+  term_AddFatherLinks(term2);
+  term2      = cnf_Cnf(term2, Precedence, Symblist);
+  Usables    = cnf_MakeClauseList(term2, FALSE, FALSE, Flags, Precedence);
+  term_Delete(term2);
+
+  for (scan=Usables; !list_Empty(scan); scan = list_Cdr(scan)) {
+    clause_SetFlag(list_Car(scan), CONCLAUSE);
+    if (flag_GetFlagValue(Flags, flag_DOCPROOF)) {
+#ifdef CHECK
+      hsh_Check(InputClauseToTermLabellist);
+#endif
+      hsh_Put(InputClauseToTermLabellist, list_Car(scan), toplabel);
+#ifdef CHECK_CNF
+      fputs("\nUsable : ", stdout);
+      clause_Print(list_Car(scan));
+      printf(" Label %s", toplabel);
+#endif
+    }
+  }
+  EmptyClauses = cnf_SatUnit(Search, Usables);
+  if (!list_Empty(EmptyClauses)) {
+    found = TRUE;
+#ifdef CHECK_CNF
+    fputs("\nHaveProof : Empty Clause : ", stdout);
+    clause_Print((CLAUSE) list_Car(EmptyClauses));
+    putchar('\n');
+#endif
+    if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+      *UsedTerms = list_Nconc(*UsedTerms, cnf_GetUsedTerms((CLAUSE) list_Car(EmptyClauses), Search, InputClauseToTermLabellist));
+    EmptyClauses = list_PointerDeleteDuplicates(EmptyClauses);
+    clause_DeleteClauseList(EmptyClauses);
+  }
+    
+  /* Removing ConClauses from UsablesIndex */
+  ConClauses = list_Copy(prfs_UsableClauses(Search));
+  for (scan = ConClauses; !list_Empty(scan); scan = list_Cdr(scan))
+    if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+      prfs_MoveUsableDocProof(Search, (CLAUSE) list_Car(scan));
+    else
+      prfs_DeleteUsable(Search, (CLAUSE) list_Car(scan));
+  list_Delete(ConClauses); 
+	
+  return found;
+}
+
+
+BOOL cnf_HaveProof(LIST TermList, TERM ToProve, FLAGSTORE InputFlags,
+		   PRECEDENCE InputPrecedence)
+/**************************************************************
+  INPUT:   A list of terms, a term to prove, a flag store and a precedence.
+           The arguments are not changed.
+  RETURNS: True if the termlist implies ToProve
+  CAUTION: All terms are copied.
+***************************************************************/
+{
+  PROOFSEARCH search;
+  LIST        scan, usables, symblist, emptyclauses;
+  BOOL        found;
+  FLAGSTORE   Flags;
+  PRECEDENCE  Precedence;
+
+  /* Use global PROOFSEARCH object to avoid stamp overflow */
+  search  = cnf_HAVEPROOFPS;
+  usables = symblist = list_Nil();
+
+  /* Initialize search object's flag store */
+  Flags = prfs_Store(search);
+  flag_CleanStore(Flags);
+  flag_InitFlotterSubproofFlags(InputFlags, Flags);
+  /* Initialize search object's precedence */
+  Precedence = prfs_Precedence(search);
+  symbol_TransferPrecedence(InputPrecedence, Precedence);
+
+  /* Build list of clauses from the termlist */
+  for (scan=TermList; !list_Empty(scan); scan=list_Cdr(scan)) {
+    TERM t;
+    t = term_Copy(list_Car(scan));
+    t = cnf_Cnf(t, Precedence, &symblist);
+
+    usables = list_Nconc(cnf_MakeClauseList(t,FALSE,FALSE,Flags,Precedence),
+			 usables);
+    term_Delete(t); 
+  }
+
+  /* Build clauses from negated term to prove */
+  ToProve = term_Create(fol_Not(), list_List(term_Copy(ToProve)));
+  term_AddFatherLinks(ToProve);
+  ToProve = cnf_Cnf(ToProve, Precedence, &symblist);
+  usables = list_Nconc(cnf_MakeClauseList(ToProve,FALSE,FALSE,Flags,Precedence),
+		       usables);
+  term_Delete(ToProve);
+
+  /* SatUnit requires the CONCLAUSE flag */
+  for (scan=usables;!list_Empty(scan); scan = list_Cdr(scan))
+    clause_SetFlag(list_Car(scan), CONCLAUSE);
+
+  emptyclauses = cnf_SatUnit(search, usables);
+  
+  if (!list_Empty(emptyclauses)) {
+    found = TRUE;
+    emptyclauses = list_PointerDeleteDuplicates(emptyclauses);
+    clause_DeleteClauseList(emptyclauses);
+  }
+  else
+    found = FALSE;
+  prfs_Clean(search);
+  symbol_DeleteSymbolList(symblist);
+
+  return found;
+}
+
+
+static void cnf_RplacVarsymbFunction(TERM term, SYMBOL varsymb, TERM function)
+/**********************************************************
+  INPUT:   A term, a variable symbol and a function.
+  EFFECT:  The variable with the symbol  varsymb in the term 
+           is replaced by the function function.
+  CAUTION: The term is destructively changed.
+***********************************************************/
+{
+  int  bottom;
+  TERM term1;
+  LIST scan;
+
+  bottom = vec_ActMax();
+  vec_Push(term);
+
+  while (bottom != vec_ActMax()) {
+    term1 = (TERM)vec_PopResult();
+    if (symbol_Equal(term_TopSymbol(term1),varsymb)) {
+      term_RplacTop(term1,term_TopSymbol(function));
+      term_RplacArgumentList(term1,term_CopyTermList(term_ArgumentList(function)));
+    }else
+      if (!list_Empty(term_ArgumentList(term1)))
+	for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan))
+	  vec_Push(list_Car(scan));
+  }
+  vec_SetMax(bottom);
+}
+
+
+static void cnf_RplacVar(TERM Term, LIST Varlist, LIST Termlist)
+/**********************************************************
+  INPUT:   A term,a variable symbol and a function.
+  RETURNS: The variable with the symbol  varsymb in the term 
+           is replaced by the function function.
+  CAUTION: The term is destructively changed.
+***********************************************************/
+{
+  int  bottom;
+  TERM term1;
+  LIST scan,scan2;
+
+  bottom = vec_ActMax();
+  vec_Push(Term);
+
+  while (bottom != vec_ActMax()) {
+    term1 = vec_PopResult();
+    if (symbol_IsVariable(term_TopSymbol(term1))) {
+      BOOL done;
+      done = FALSE;
+      for (scan=Varlist, scan2=Termlist; !list_Empty(scan) && !done; 
+	   scan = list_Cdr(scan), scan2 = list_Cdr(scan2)) {
+	if (symbol_Equal(term_TopSymbol(term1),term_TopSymbol(list_Car(scan)))) {
+	  term_RplacTop(term1,term_TopSymbol((TERM) list_Car(scan2)));
+	  term_RplacArgumentList(term1,
+				 term_CopyTermList(term_ArgumentList(list_Car(scan2))));
+	  done = TRUE;
+	}
+      }
+    }
+    else
+      if (!list_Empty(term_ArgumentList(term1)))
+	for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan))
+	  vec_Push(list_Car(scan));
+  }
+  vec_SetMax(bottom);
+}
+
+
+static TERM cnf_MakeSkolemFunction(LIST varlist, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A list of variables and a precedence.
+  RETURNS: The new term oskf... (oskc...) which is a function 
+           with varlist as arguments.
+  EFFECT:  The precedence of the new Skolem function is set in <Precedence>.
+***************************************************************/
+{
+  TERM   term;
+  SYMBOL skolem;
+  
+  skolem = symbol_CreateSkolemFunction(list_Length(varlist), Precedence);
+  term   = term_Create(skolem, term_CopyTermList(varlist));
+  return term;
+}
+
+
+static void cnf_PopAllQuantifier(TERM term)
+/********************************************************
+ INPUT:   A term whose top symbol is fol_all.
+ RETURNS: Nothing.
+ EFFECT:  Removes the quantifier
+********************************************************/
+{
+  TERM SubTerm;
+  LIST VarList;
+
+#ifdef CHECK
+  if (!symbol_Equal(term_TopSymbol(term), fol_All())) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cnf_PopAllQuantifier: Top symbol is not fol_All !\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  VarList = term_ArgumentList(term_FirstArgument(term));
+  term_DeleteTermList(VarList);
+  term_Free(term_FirstArgument(term));
+  SubTerm = term_SecondArgument(term);
+  list_Delete(term_ArgumentList(term));
+  term_RplacTop(term,term_TopSymbol(SubTerm));
+  term_RplacArgumentList(term,term_ArgumentList(SubTerm));
+  term_Free(SubTerm);
+}
+
+
+static TERM cnf_QuantifyAndNegate(TERM term, LIST VarList, LIST FreeList)
+/****************************************************************
+  INPUT:   A term, a list of variables to be exist-quantified,
+           a list of variables to be all-quantified
+  RETURNS: not(forall[FreeList](exists[VarList](term)))
+  MEMORY:  The term, the lists and their arguments are copied.
+***************************************************************/
+{
+  TERM Result;
+  TERM TermCopy;
+  LIST VarListCopy;
+  LIST FreeListCopy;
+
+  TermCopy = term_Copy(term);
+  VarListCopy = term_CopyTermList(VarList);
+  Result = fol_CreateQuantifier(fol_Exist(),VarListCopy,list_List(TermCopy));
+  FreeListCopy = list_Nil();
+
+  FreeList = fol_FreeVariables(Result);
+  if (!list_Empty(FreeList)) {
+    FreeListCopy = term_CopyTermList(FreeList);
+    list_Delete(FreeList);
+    Result = fol_CreateQuantifier(fol_All(), FreeListCopy, list_List(Result));
+  }
+  Result = term_Create(fol_Not(), list_List(Result));
+  return Result;
+}
+
+
+static TERM cnf_MoveProvedTermToTopLevel(TERM Term, TERM Term1, TERM Proved,
+					 LIST VarList, LIST FreeList,
+					 PRECEDENCE Precedence)
+/********************************************************************
+  INPUT:   A top-level term, which must be a conjunction,
+           a subterm <Term1> of <Term>, a subterm <Proved> of <Term1>,
+	   a list of existence quantified variables <VarList>,
+	   a list of free variables <FreeList> and a precedence.
+           <Term1> is of the form
+	   exists[...](t1 and t2 and ... and Proved and ..)
+  RETURNS: A new term, where <Proved> is removed from the arguments
+           of <Term1>.
+  EFFECT:  The precedence of new Skolem functions is set in <Precedence>
+*******************************************************************/
+{
+  TERM termR;
+  TERM skolemfunction;
+  SYMBOL varsymb;
+  LIST scan;
+
+  termR = term_SecondArgument(Term1); /* t1 and t2 and ... and Proved ... */
+  term_RplacArgumentList(termR,
+			 list_PointerDeleteElement(term_ArgumentList(termR),
+						   Proved));
+  if (list_Length(term_ArgumentList(termR)) < 2) {
+    TERM termRL = term_FirstArgument(termR);     /* t1 */
+    list_Delete(term_ArgumentList(termR));
+    term_RplacTop(termR, term_TopSymbol(termRL));
+    term_RplacArgumentList(termR,term_ArgumentList(termRL));
+    term_Free(termRL);
+  }
+
+  for (scan = VarList; scan != list_Nil(); scan = list_Cdr(scan)) {
+    varsymb = term_TopSymbol(list_Car(scan));
+    skolemfunction = cnf_MakeSkolemFunction(FreeList, Precedence);
+    cnf_RplacVarsymbFunction(termR,varsymb,skolemfunction);
+    cnf_RplacVarsymbFunction(Proved,varsymb,skolemfunction); 
+    term_Delete(skolemfunction); 
+  }
+
+  if (!list_Empty(FreeList)) {
+    Proved = 
+      fol_CreateQuantifier(fol_All(), term_CopyTermList(FreeList),
+			   list_List(Proved));
+    if (list_Length(FreeList) > 1)
+      Proved = cnf_QuantMakeOneVar(Proved);
+  }
+ 
+  term_Delete(term_FirstArgument(Term1)); /* Variables of "exists" */
+  list_Delete(term_ArgumentList(Term1));
+  term_RplacTop(Term1,term_TopSymbol(termR));
+  term_RplacArgumentList(Term1,term_ArgumentList(termR));
+  term_Free(termR);
+    
+  term_RplacArgumentList(Term, list_Cons(Proved, term_ArgumentList(Term)));
+  return Proved;
+}
+
+
+static void cnf_Skolemize(TERM Term, LIST FreeList, PRECEDENCE Precedence)
+/********************************************************
+  INPUT:   A existence quantified term, the list of free variables
+           and a precedence.
+  RETURNS: Nothing.
+  EFFECT:  The term is destructively changed, i.e. the
+           existence quantifier is removed by skolemization.
+	   The precedence of new Skolem functions is set in <Precedence>.
+*********************************************************/
+{
+  LIST exlist;
+  TERM subterm;
+  LIST symblist;
+
+  symblist = list_Nil();
+  exlist = cnf_GetSymbolList(term_ArgumentList(term_FirstArgument(Term)));
+  term_Delete(term_FirstArgument(Term));
+  subterm = term_SecondArgument(Term);
+  list_Delete(term_ArgumentList(Term));
+  term_RplacTop(Term,term_TopSymbol(subterm));
+  term_RplacArgumentList(Term,term_ArgumentList(subterm));
+  term_Free(subterm);
+  symblist = cnf_SkolemFunctionFormula(Term, FreeList, exlist, Precedence);
+  list_Delete(exlist);
+  list_Delete(symblist);
+}
+
+
+static LIST cnf_FreeVariablesBut(TERM Term, LIST Symbols)
+/********************************************************
+  INPUT:   A term and a list of symbols
+  RETURNS: A list of all free variable terms in Term whose symbols are 
+           not in Symbols
+*********************************************************/
+{
+  LIST follist, Scan;
+  follist = fol_FreeVariables(Term);
+  for (Scan = follist; !list_Empty(Scan); Scan = list_Cdr(Scan))
+    if (list_Member(Symbols, (POINTER)term_TopSymbol(list_Car(Scan)),
+		    (BOOL (*)(POINTER,POINTER))symbol_Equal))
+      list_Rplaca(Scan,NULL);
+  follist = list_PointerDeleteElement(follist,NULL);
+    
+  return follist;
+}
+
+
+static void cnf_SkolemFunctionFormulaMapped(TERM term, LIST allist, LIST map)
+/**************************************************************
+  INPUT:   A term  term and a  list allist of variables and a list map
+           of pairs (variable symbols, function symbol)
+  RETURNS: None.
+  CAUTION: The term is destructively changed. All variable symbols
+           in map which appear in term are replaced by the skolem functions
+	   with respect to allist which contains the universally quantified
+	   variables.
+***************************************************************/
+{
+  TERM   term1;
+  LIST   scan,scan1;
+  SYMBOL skolem, symbol;
+  int    bottom;
+
+  bottom = vec_ActMax();
+  
+  for (scan1=map; !list_Empty(scan1); scan1=list_Cdr(scan1)) {
+    vec_Push(term);
+    symbol = (SYMBOL) list_PairFirst((LIST) list_Car(scan1));
+    skolem = (SYMBOL) list_PairSecond((LIST) list_Car(scan1));
+
+#ifdef CHECK_STRSKOLEM
+    if (flag_GetFlagValue(flag_PSTRSKOLEM)) {
+      fputs("\nVariable : ", stdout);
+      symbol_Print(symbol);
+      fputs("\nFunction : ", stdout);
+      symbol_Print(skolem);
+    }
+#endif
+    while (bottom != vec_ActMax()) {
+      term1 = (TERM)vec_PopResult();
+
+      if (symbol_Equal(term_TopSymbol(term1),symbol)) {
+	term_RplacTop(term1,skolem);
+	list_Delete(term_ArgumentList(term1));
+	term_RplacArgumentList(term1,term_CopyTermList(allist));
+      }
+      if (!list_Empty(term_ArgumentList(term1)))
+	for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan)) {
+	  vec_Push(list_Car(scan));
+	}
+    }
+  }
+  vec_SetMax(bottom);
+}
+
+
+static BOOL cnf_HasDeeperVariable(LIST List1, LIST List2)
+/******************************************************************
+   INPUT:   Two lists of variable terms
+   RETURNS: TRUE if a variable in the first list is deeper than all variables
+            in the second list, FALSE otherwise.
+   NOTE:    If cnf_VARIABLEDEPTHARRAY is not allocated this will crash
+            If new variables are introduced by strong skolemization, their
+            depth is -1.
+*******************************************************************/
+{
+  LIST scan;
+  int  maxdepth1;
+  
+  /* Determine maximum depth of variables in List1 */
+  maxdepth1 = 0;
+  for (scan=List1; !list_Empty(scan); scan=list_Cdr(scan)) {
+    int i;
+    i = cnf_VARIABLEDEPTHARRAY[term_TopSymbol((TERM) list_Car(scan))];
+#ifdef CHECK_STRSKOLEM
+    if (flag_GetFlagValue(flag_PSTRSKOLEM)) {
+      fputs("\nFor variable ", stdout);
+      symbol_Print(term_TopSymbol((TERM) list_Car(scan)));
+      printf(" depth is %d.", i);
+    }
+#endif
+    if (i > maxdepth1)
+      maxdepth1 = i;
+  }
+
+  /* Compare with depth of variables in List2 */
+  for (scan=List2; !list_Empty(scan); scan=list_Cdr(scan)) {
+    int i;
+    i = cnf_VARIABLEDEPTHARRAY[term_TopSymbol((TERM) list_Car(scan))];
+#ifdef CHECK_STRSKOLEM
+    if (flag_GetFlagValue(flag_PSTRSKOLEM)) {
+      fputs("\nFor variable ", stdout);
+      symbol_Print(term_TopSymbol((TERM) list_Car(scan)));
+      printf(" depth is %d.", i);
+    }
+#endif
+    if (i >= maxdepth1)
+      return FALSE;
+  }
+  return  TRUE;
+}
+
+
+static void cnf_StrongSkolemization(PROOFSEARCH Search, TERM Topterm,
+				    char* Toplabel, BOOL TopAnd, TERM Term, 
+				    LIST* UsedTerms, LIST* Symblist,
+				    BOOL Result1,
+				    HASH InputClauseToTermLabellist, int Depth)
+/******************************************************************
+  INPUT:   An existence quantified formula. ??? EK
+  RETURNS: Nothing.
+  EFFECT:  The existence quantifier is removed by strong skolemization.
+           The precedence of new Skolem symbols is set in the precedence
+	   of the search object.
+*******************************************************************/
+{
+  LIST       exlist;    /* Variable symbols bound by exists[]() */
+  LIST       pairlist;  /* List of pairs (Subterm of AND, free variable symbols
+			   not in exlist) */
+  LIST       allfreevariables;
+  LIST       newvariables;       /* w2..wn*/
+  LIST       mapping;           /* List of pairs */
+  int        numberofallfreevariables, acc_length, i;
+  LIST       pair, pairscan, pairscan_pred, scan, accumulatedvariables;
+  TERM       subterm, w;
+  BOOL       strskolemsuccess;  /* Indicates whether strong skolemization was
+				   possible */
+  FLAGSTORE  Flags;
+  PRECEDENCE Precedence;
+
+  Flags      = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+
+  /* Necessary so that new variables really are new ! */
+  if (flag_GetFlagValue(Flags, flag_CNFSTRSKOLEM))
+    symbol_SetStandardVarCounter(term_MaxVar(Topterm));
+
+  /* Get list of quantified variable symbols x_k */
+  exlist = cnf_GetSymbolList(term_ArgumentList(term_FirstArgument(Term)));
+  /* Pop quantifier */
+  term_Delete(term_FirstArgument(Term));
+  subterm = term_SecondArgument(Term);
+  list_Delete(term_ArgumentList(Term));
+  term_RplacTop(Term,term_TopSymbol(subterm));
+  term_RplacArgumentList(Term,term_ArgumentList(subterm));
+  term_Free(subterm);
+
+  /* Now for every argument get the list of free variables whose symbols
+     are not in exlist */
+  pairlist = list_Nil();
+  for (scan=term_ArgumentList(Term); !list_Empty(scan); scan = list_Cdr(scan)) {
+    pair = list_PairCreate((TERM) list_Car(scan), 
+			   cnf_FreeVariablesBut((TERM) list_Car(scan), exlist));
+    if (list_Empty(pairlist)) 
+      pairlist = list_List(pair);
+    else {
+      /* First sort subterms by number of free variables */
+      int pairlength, currentlength;
+      pairlength = list_Length((LIST) list_PairSecond(pair));
+      pairscan = pairlist; 
+      pairscan_pred = list_Nil();
+      currentlength = 0;
+      while (!list_Empty(pairscan)) {
+	currentlength = list_Length((LIST) list_PairSecond((LIST) list_Car(pairscan)));
+	if (currentlength < pairlength) {
+	  pairscan_pred = pairscan;
+	  pairscan = list_Cdr(pairscan);
+	}
+	else if (currentlength == pairlength) {
+	  /* If both subterms have the same number of free variables compare depth of variables */
+	  if (cnf_HasDeeperVariable((LIST) list_PairSecond((LIST) list_Car(pairscan)), /* in list */
+				   (LIST) list_PairSecond(pair))) {                   /* new pair */
+#ifdef CHECK_STRSKOLEM
+	    if (flag_GetFlagValue(flag_PSTRSKOLEM)) {
+	      fputs("\nTerm ", stdout);
+	      term_Print((TERM) list_PairFirst((LIST) list_Car(pairscan)));
+	      fputs("\n has deeper variable than ", stdout);
+	      term_Print((TERM) list_PairFirst(pair));
+	    }
+#endif	    
+	    pairscan_pred = pairscan;
+	    pairscan = list_Cdr(pairscan);
+	  }
+	  else
+	    break;
+	}
+	else
+	  break;
+      }
+      
+      /* New pair has more variables than all others in list */
+      if (list_Empty(pairscan))
+	list_Rplacd(pairscan_pred, list_List(pair));
+      /* New pair is inserted between pairscan_pred and pairscan */
+      else if (currentlength >= pairlength) { 
+	/* Head of list */
+	if (list_Empty(pairscan_pred))
+	  pairlist = list_Cons(pair, pairlist);
+	else 
+	  list_InsertNext(pairscan_pred, pair);
+      }
+      /* The case for the same number of variables is not yet implemented */
+    }
+  }
+
+#ifdef CHECK_STRSKOLEM
+  if (flag_GetFlagValue(flag_PSTRSKOLEM)) {
+    for (pairscan=pairlist; !list_Empty(pairscan); pairscan = list_Cdr(pairscan)) {
+      LIST l;
+      fputs("\nSubterm ", stdout);
+      term_Print((TERM) list_PairFirst((LIST) list_Car(pairscan)));
+      fputs("\n  has free variables ", stdout);
+      for (l=(LIST) list_PairSecond((LIST) list_Car(pairscan)); !list_Empty(l); l = list_Cdr(l)) {
+	term_Print((TERM) list_Car(l));
+	fputs(" ", stdout);
+      }
+    }
+  }
+#endif
+
+  /* Determine number of all free variablein and()--term whose symbols are not in exlist */
+  /* Create map from ex_variables tp skolem symbols */
+  allfreevariables = cnf_FreeVariablesBut(Term, exlist);
+  numberofallfreevariables = list_Length(allfreevariables);
+    
+  mapping  = list_Nil();
+
+  for (scan = exlist; !list_Empty(scan); scan = list_Cdr(scan)) {
+    SYMBOL skolem;
+    skolem = symbol_CreateSkolemFunction(numberofallfreevariables, Precedence);
+    *Symblist = list_Cons((POINTER)skolem,*Symblist);
+    mapping = list_Cons(list_PairCreate(list_Car(scan), (POINTER)skolem), 
+			mapping);
+  }
+  list_Delete(allfreevariables);
+
+  /* Create new variables */
+  newvariables = list_Nil();
+
+  for (i=0; i < numberofallfreevariables; i++) {
+    w = term_CreateStandardVariable();
+    newvariables = list_Cons(w, newvariables);
+  }
+
+#ifdef CHECK_STRSKOLEM
+  if (flag_GetFlagValue(flag_PSTRSKOLEM)) {
+    LIST l;
+    fputs("\nNew variables : ", stdout);
+    for (l=newvariables; !list_Empty(l); l = list_Cdr(l)) {
+      term_Print((TERM) list_Car(l));
+      fputs(" ", stdout);
+    }
+  }
+#endif
+  
+  /* Now do the replacing */
+  accumulatedvariables = list_Nil();
+  acc_length = 0;
+  strskolemsuccess = FALSE;
+  for (pairscan=pairlist; !list_Empty(pairscan); pairscan=list_Cdr(pairscan)) {
+    LIST allist;
+
+    /* Add bound variables for this subterm */
+    accumulatedvariables = list_Nconc(accumulatedvariables,
+				      (LIST) list_PairSecond((LIST) list_Car(pairscan)));
+    accumulatedvariables = term_DeleteDuplicatesFromList(accumulatedvariables);
+
+    /* Remove new variables not (no longer) needed */
+    for (i=0; i < list_Length(accumulatedvariables) - acc_length; i++) {
+      term_Delete((TERM) list_Top(newvariables));
+      newvariables = list_Pop(newvariables);
+    }
+    acc_length = list_Length(accumulatedvariables);
+
+#ifdef CHECK_STRSKOLEM
+    if (flag_GetFlagValue(flag_PSTRSKOLEM)) {
+      LIST l;
+      fputs("\n\nSubterm is ", stdout);
+      term_Print((TERM) list_PairFirst((LIST) list_Car(pairscan)));
+      fputs("\nFree variables : ", stdout);
+      for (l=accumulatedvariables; !list_Empty(l); l = list_Cdr(l)) {
+	term_Print((TERM) list_Car(l));
+	fputs(" ", stdout);
+      }
+    }
+#endif
+    if (!list_Empty(newvariables))
+      strskolemsuccess = TRUE;
+    allist = list_Nconc(list_Copy(accumulatedvariables), list_Copy(newvariables));
+
+    cnf_SkolemFunctionFormulaMapped((TERM) list_PairFirst((LIST) list_Car(pairscan)), allist,
+				    mapping);
+#ifdef CHECK_STRSKOLEM
+    if (flag_GetFlagValue(flag_PSTRSKOLEM)) {
+      fputs("\nSubterm after skolemization : ", stdout);
+      term_Print(list_PairFirst((LIST) list_Car(pairscan)));
+    }
+#endif
+
+    list_Delete(allist);
+    cnf_OptimizedSkolemFormula(Search, Topterm, Toplabel, TopAnd,
+			       (TERM) list_PairFirst((LIST) list_Car(pairscan)),
+			       UsedTerms, Symblist, Result1, 
+			       InputClauseToTermLabellist, Depth);
+  }
+  while (!list_Empty(newvariables)) {
+    term_Delete((TERM) list_Top(newvariables));
+    newvariables = list_Pop(newvariables);
+  }
+  list_Delete(accumulatedvariables); /* Only pairs and pairlist left */
+  list_DeletePairList(pairlist);
+  list_Delete(exlist);
+  list_DeletePairList(mapping);
+  if (flag_GetFlagValue(Flags, flag_PSTRSKOLEM) && strskolemsuccess) {
+    fputs("\nStrong skolemization applied", stdout);
+  }
+}
+    
+
+static void cnf_OptimizedSkolemFormula(PROOFSEARCH Search, TERM topterm,
+				       char* toplabel, BOOL TopAnd, TERM term, 
+				       LIST* UsedTerms, LIST* Symblist,
+				       BOOL Result1,
+				       HASH InputClauseToTermLabellist,
+				       int Depth)
+/**************************************************************
+  INPUT:   Two terms in negation normal form. ??? EK
+  RETURNS: The  skolemized term with the optimized skolemization
+           due to Ohlbach and Weidenbach of <term> and further improvements.
+	   <rest> is used as additional, conjunctively added information.
+  EFFECT:  The symbol precedence of the search  object is changed
+           because new Skolem symbols are defined.
+  CAUTION: The term is destructively changed.
+***************************************************************/
+{
+  TERM       termL2, provedterm;
+  LIST       freevariables, scan, varlist;
+  SYMBOL     top;
+  BOOL       result2;
+  BOOL       optimized;
+  FLAGSTORE  Flags;
+  PRECEDENCE Precedence;
+
+  result2       = FALSE;
+  freevariables = list_Nil();
+  Flags         = prfs_Store(Search);
+  Precedence    = prfs_Precedence(Search);
+  
+  top = term_TopSymbol(term);
+  if (fol_IsQuantifier(top)) {
+    if (symbol_Equal(top,fol_All())) {
+      /* For quantified variables store depth if strong skolemization is performed */
+      if (flag_GetFlagValue(Flags, flag_CNFSTRSKOLEM)) {
+	LIST variables;
+	variables = term_ArgumentList(term_FirstArgument(term));
+	for (scan=variables; !list_Empty(scan); scan=list_Cdr(scan)) {
+#ifdef CHECK_STRSKOLEM
+	  if (flag_GetFlagValue(Flags, flag_PSTRSKOLEM)) {
+	    if (cnf_VARIABLEDEPTHARRAY[term_TopSymbol(list_Car(scan))] != -1) {
+	      fputs("\nFor variable ", stderr);
+	      term_Print((TERM) list_Car(scan));
+	      printf(" depth is already set to %d, now setting it to %d", 
+		     cnf_VARIABLEDEPTHARRAY[term_TopSymbol(list_Car(scan))],Depth);
+	    }
+	  }
+#endif
+#ifdef CHECK_STRSKOLEM
+	  if (flag_GetFlagValue(Flags, flag_PSTRSKOLEM)) {
+	    fputs("\nVariable ", stdout);
+	    term_Print((TERM) list_Car(scan));
+	    printf(" has depth %d in term\n  ", Depth);
+	    term_Print(term);
+	  }
+#endif
+	  cnf_VARIABLEDEPTHARRAY[term_TopSymbol(list_Car(scan))] = Depth;
+	}
+	Depth++;
+      }
+      cnf_PopAllQuantifier(term);
+      cnf_OptimizedSkolemFormula(Search,topterm, toplabel, TopAnd, term, 
+				 UsedTerms, Symblist, Result1,
+				 InputClauseToTermLabellist, Depth);
+      return;
+    }
+    freevariables = fol_FreeVariables(term);
+    optimized = FALSE;
+    if (symbol_Equal(term_TopSymbol(term_SecondArgument(term)), fol_And())) {
+      if (flag_GetFlagValue(Flags, flag_CNFOPTSKOLEM)) {
+	scan = term_ArgumentList(term_SecondArgument(term));
+	varlist = term_ArgumentList(term_FirstArgument(term));
+	while (!list_Empty(scan) && !optimized) {
+	  if (!Result1) {
+	    if (TopAnd) {
+	      if (flag_GetFlagValue(Flags, flag_POPTSKOLEM)) {
+		fputs("\nHaveProof not necessary", stdout);
+	      }
+	      result2 = TRUE;
+	    }
+	    else {
+	      termL2 = cnf_QuantifyAndNegate((TERM) list_Car(scan), 
+					     varlist, freevariables);
+	      result2 = cnf_HaveProofOptSkolem(Search, topterm, toplabel, termL2,
+					       UsedTerms, Symblist, 
+					       InputClauseToTermLabellist);
+#ifdef CHECK_OPTSKOLEM
+	      if (flag_GetFlagValue(Flags, flag_POPTSKOLEM)) {
+		fputs("\nHaveProof result : ", stdout);
+		if (result2)
+		  fputs("TRUE", stdout);
+		else
+		  fputs("FALSE", stdout);
+	      }
+#endif
+	    }
+	  }
+	    
+	  if (Result1 || result2) {
+	    optimized = TRUE;
+	    if (flag_GetFlagValue(Flags, flag_POPTSKOLEM)) {
+	      fputs("\nIn term ", stdout);
+	      term_Print(topterm);
+	      fputs("\n subterm ", stdout);
+	      term_Print((TERM) list_Car(scan));
+	      puts(" is moved to toplevel.");
+	    }
+	    provedterm =
+	      cnf_MoveProvedTermToTopLevel(topterm, term, list_Car(scan), 
+					   varlist, freevariables, Precedence);
+	    if (flag_GetFlagValue(Flags, flag_POPTSKOLEM)) {
+	      fputs("Result : ", stdout);
+	      term_Print(topterm);
+	      putchar('\n');
+	    }
+	    /* provedterm is argument of top AND term */
+	    cnf_OptimizedSkolemFormula(Search, topterm, toplabel, TRUE,
+				       provedterm,UsedTerms, Symblist, Result1, 
+				       InputClauseToTermLabellist, Depth);
+	  }
+	  else 
+	    scan = list_Cdr(scan);
+	}
+      }
+      if (!optimized) {
+	/* Optimized skolemization not enabled or not possible */
+	if (flag_GetFlagValue(Flags, flag_CNFSTRSKOLEM)) {
+	  optimized = TRUE; /* Strong Skolemization is always possible after exists[..](and(..)) */
+	  cnf_StrongSkolemization(Search, topterm, toplabel, TopAnd, term,
+				  UsedTerms, Symblist, Result1, 
+				  InputClauseToTermLabellist, Depth);
+	}
+      }
+    }
+    else
+      TopAnd = FALSE;
+    if (!optimized) {
+      /* Optimized skolemization not enabled or not possible */
+      /* Strong skolemization not enabled or not possible */
+      cnf_Skolemize(term, freevariables, Precedence);
+    }
+    list_Delete(freevariables);
+    cnf_OptimizedSkolemFormula(Search, topterm, toplabel, TopAnd, term,UsedTerms,
+			       Symblist,Result1,InputClauseToTermLabellist,Depth);
+    return;
+  } 
+  else {
+    if (symbol_Equal(top,fol_And()) || symbol_Equal(top,fol_Or())) {
+      if (symbol_Equal(top,fol_Or()))
+	TopAnd = FALSE;
+      for (scan=term_ArgumentList(term);!list_Empty(scan);
+	   scan=list_Cdr(scan))
+	cnf_OptimizedSkolemFormula(Search, topterm, toplabel, TopAnd,
+				   (TERM) list_Car(scan),
+				   UsedTerms, Symblist,
+				   Result1, InputClauseToTermLabellist, Depth);
+    }
+  }
+  return;
+}
+
+
+static LIST cnf_SkolemFunctionFormula(TERM term, LIST allist, LIST exlist,
+				      PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A term <term>, a list <allist> of variables, a list <exlist>
+           of variable symbols and a precedence.
+  RETURNS: The list of new Skolem functions.
+  EFFECT:  The term is destructively changed. All variable symbols
+           in <exlist> which appear in <term> are replaced by skolem functions
+	   with respect to <allist> which contains the universally quantified
+	   variables.
+	   New Skolem functions are created and their precedence is set
+	   in <Precedence>.
+***************************************************************/
+{
+  TERM   term1;
+  LIST   scan, scan1, Result;
+  SYMBOL skolem;
+  int    bottom,n;
+
+  Result = list_Nil();
+  bottom = vec_ActMax();
+  n = list_Length(allist);
+  
+  for (scan1=exlist; !list_Empty(scan1); scan1=list_Cdr(scan1)) {
+    vec_Push(term);
+    skolem = symbol_CreateSkolemFunction(n, Precedence);
+    Result = list_Cons((POINTER)skolem, Result);
+    
+    while (bottom != vec_ActMax()) {
+      term1 = (TERM)vec_PopResult();
+      if (symbol_Equal(term_TopSymbol(term1),(SYMBOL)list_Car(scan1))) {
+	term_RplacTop(term1,skolem);
+	list_Delete(term_ArgumentList(term1));
+	term_RplacArgumentList(term1,term_CopyTermList(allist));
+      }
+      if (!list_Empty(term_ArgumentList(term1)))
+	for (scan=term_ArgumentList(term1);!list_Empty(scan);scan=list_Cdr(scan))
+	  vec_Push(list_Car(scan));
+    }
+  }
+  vec_SetMax(bottom);
+  return Result;
+}
+
+
+static LIST cnf_OptimizedSkolemization(PROOFSEARCH Search, TERM Term,
+				       char* Label, LIST* UsedTerms, 
+				       LIST* Symblist, BOOL result,
+				       BOOL Conjecture, 
+				       HASH InputClauseToTermLabellist)
+/**************************************************************
+  INPUT:   A term, a shared index and a list of non-ConClauses. ??? EK
+  RETURNS: The list of clauses derived from Term.
+  EFFECT:  The term is skolemized using optimized skolemization wrt ShIndex.
+**************************************************************/
+{
+  LIST       Clauses;
+  TERM       FirstArg;
+  int        i;
+  FLAGSTORE  Flags;
+  PRECEDENCE Precedence;
+
+#ifdef CHECK
+  if (Term == NULL) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cnf_OptimizedSkolemization: Input term is NULL.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Flags      = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+  FirstArg   = Term;
+
+  if (flag_GetFlagValue(Flags, flag_CNFSTRSKOLEM)) {
+    /* Initializing array */
+    for (i = 1; i <= symbol__MAXSTANDARDVAR; i++)
+      cnf_VARIABLEDEPTHARRAY[i] = -1;
+  }
+
+  if (flag_GetFlagValue(Flags, flag_POPTSKOLEM) ||
+      flag_GetFlagValue(Flags, flag_PSTRSKOLEM)) {
+    fputs("\nTerm before skolemization : \n ", stdout);
+    fol_PrettyPrintDFG(Term);
+  }
+
+  if (!fol_IsLiteral(Term)) {
+    if (flag_GetFlagValue(Flags, flag_CNFOPTSKOLEM) ||
+	flag_GetFlagValue(Flags, flag_CNFSTRSKOLEM))  {
+      if (flag_GetFlagValue(Flags, flag_CNFOPTSKOLEM))
+	Term = term_Create(fol_And(), list_List(Term)); /* CW hack: definitions are added on top level*/
+      cnf_OptimizedSkolemFormula(Search, Term, Label, TRUE, FirstArg, UsedTerms, 
+				 Symblist, result, InputClauseToTermLabellist, 0);
+    }
+    else {
+      LIST Symbols;
+      Symbols = list_Nil();
+      Term    = cnf_SkolemFormula(Term, Precedence, &Symbols);
+      list_Delete(Symbols);
+    }
+  }
+  if (flag_GetFlagValue(Flags, flag_POPTSKOLEM) ||
+      flag_GetFlagValue(Flags, flag_PSTRSKOLEM)) {
+    fputs("\nTerm after skolemization : ", stdout);
+    term_Print(Term);
+  }
+  Term    = cnf_DistributiveFormula(Term);
+  Clauses = cnf_MakeClauseList(Term, FALSE, Conjecture, Flags, Precedence);
+  term_Delete(Term);
+
+  return Clauses;
+}
+
+
+LIST cnf_GetSkolemFunctions(TERM Term, LIST ArgList, LIST* SkolToExVar)
+/**************************************************************
+  INPUT:   A term, the argumentlist of a skolem function, a mapping from
+           a skolem function to a variable
+  RETURNS: The longest argumentlist of all skolem functions found so far.
+  EFFECT:  Computes information for renaming variables and replacing 
+           skolem functions during de-skolemization.
+**************************************************************/ 
+{
+  LIST Scan;
+  SYMBOL Top;
+    
+  Top = term_TopSymbol(Term);
+
+  if (fol_IsQuantifier(Top)) 
+    return cnf_GetSkolemFunctions(term_SecondArgument(Term), ArgList, 
+				  SkolToExVar);
+
+  if (symbol_IsFunction(Top) && symbol_HasProperty(Top, SKOLEM)) {
+    BOOL found;
+    SYMBOL Var = 0;
+    int Arity;
+    found = FALSE;
+      
+    /* Keep longest argument list of all skolem functions in the clause for renaming */
+    /* Delete all other argument lists */
+    Arity = list_Length(term_ArgumentList(Term));
+    if (Arity > list_Length(ArgList)) {
+      term_DeleteTermList(ArgList);
+      ArgList = term_ArgumentList(Term);
+    }
+    else 
+      term_DeleteTermList(term_ArgumentList(Term));
+    term_RplacArgumentList(Term, NULL);
+      
+    /* Replace skolem function by variable */
+    if (list_Length(*SkolToExVar) > Arity) {
+      NAT i;
+      LIST SkolScan = *SkolToExVar;
+      for (i = 0; i < Arity; i++)
+	SkolScan = list_Cdr(SkolScan);
+      for (SkolScan = (LIST) list_Car(SkolScan);
+	   (SkolScan != list_Nil()) && !found; SkolScan = list_Cdr(SkolScan)) {
+	SYMBOL Skol;
+	Skol = (SYMBOL) list_PairFirst((LIST) list_Car(SkolScan));
+	if (Skol == term_TopSymbol(Term)) {
+	  Var = (SYMBOL) list_PairSecond((LIST) list_Car(SkolScan));
+	  found = TRUE;
+	}
+      }
+    }
+    if (!found) {
+      LIST Pair;
+      NAT  i;
+      LIST SkolScan;
+
+      SkolScan = *SkolToExVar;
+      for (i = 0; i < Arity; i++) {
+	if (list_Cdr(SkolScan) == list_Nil())
+	  list_Rplacd(SkolScan, list_List(NULL));
+	SkolScan = list_Cdr(SkolScan);
+      }
+
+      Var = symbol_CreateStandardVariable();
+      Pair = list_PairCreate((POINTER) term_TopSymbol(Term), 
+			     (POINTER) Var);
+      if (list_Car(SkolScan) == list_Nil())
+	list_Rplaca(SkolScan, list_List(Pair));
+      else
+	list_Rplaca(SkolScan, list_Nconc((LIST) list_Car(SkolScan), 
+					 list_List(Pair)));
+    }
+    term_RplacTop(Term, Var);
+  }
+  else {
+    for (Scan = term_ArgumentList(Term); Scan != list_Nil(); 
+	Scan = list_Cdr(Scan))
+      ArgList = cnf_GetSkolemFunctions((TERM) list_Car(Scan), ArgList, 
+				       SkolToExVar);
+  }
+  return ArgList;
+}
+
+
+void cnf_ReplaceVariable(TERM Term, SYMBOL Old, SYMBOL New)
+/**************************************************************
+  INPUT:  A term, two symbols that are variables
+  EFFECT: In term every occurrence of Old is replaced by New
+**************************************************************/ 
+{
+  LIST Scan;
+
+#ifdef CHECK
+  if (!symbol_IsVariable(Old)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cnf_ReplaceVariable: Illegal input symbol.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (symbol_Equal(term_TopSymbol(Term), Old))
+    term_RplacTop(Term, New);
+  else 
+    for (Scan = term_ArgumentList(Term); !list_Empty(Scan); 
+	 Scan = list_Cdr(Scan))
+      cnf_ReplaceVariable(list_Car(Scan), Old, New);
+}
+
+
+LIST cnf_RemoveSkolemFunctions(CLAUSE Clause, LIST* SkolToExVar, LIST Vars)
+/**************************************************************
+  INPUT:   A clause, a list which is a mapping from skolem functions to
+           variables and a list of variables for forall-quantification.
+  RETURNS: A list of terms derived from the clause using deskolemization
+  EFFECT:  Arguments of skolem functions are renamed consistently.
+           Skolemfunctions are replaced by variables.
+**************************************************************/
+{
+  LIST Scan;
+  LIST TermScan, TermList, ArgList;
+  TERM Term;
+  int i;
+
+  TermList = list_Nil();
+
+  ArgList = list_Nil();
+  for (i = 0; i < clause_Length(Clause); i++) {
+    Term = term_Copy(clause_GetLiteralTerm(Clause, i));
+    ArgList = cnf_GetSkolemFunctions(Term, ArgList, SkolToExVar);
+    TermList = list_Cons(Term, TermList);
+  }
+    
+  if (list_Empty(ArgList))
+    return TermList;
+    
+  /* Rename variables */
+  for (Scan = ArgList; Scan != list_Nil(); Scan = list_Cdr(Scan)) {
+    for (TermScan = TermList; TermScan != list_Nil(); 
+	 TermScan = list_Cdr(TermScan)) {
+      Term = (TERM) list_Car(TermScan);
+      cnf_ReplaceVariable(Term,
+			  term_TopSymbol((TERM) list_Car(Scan)),
+			  (SYMBOL) list_Car(Vars));
+    }
+    if (list_Cdr(Vars) == list_Nil()) {
+      SYMBOL New = symbol_CreateStandardVariable();
+      Vars = list_Nconc(Vars, list_List((POINTER) New));
+    }
+    Vars = list_Cdr(Vars);
+  }
+  term_DeleteTermList(ArgList);
+  return TermList;
+}
+
+
+TERM cnf_DeSkolemFormula(LIST Clauses)
+/**************************************************************
+  INPUT:   A list of clauses.
+  RETURNS: A formula built from the clauses.
+  EFFECT:  All skolem functions are removed from the clauses.
+**************************************************************/
+{
+  LIST Scan, SkolToExVar, Vars, FreeVars, FreeVarsCopy, VarScan, TermList;
+  TERM VarListTerm, TopTerm, Term;
+  BOOL First;
+  
+  SkolToExVar = list_List(NULL);
+  Vars = list_List((POINTER) symbol_CreateStandardVariable());
+  
+  TopTerm = term_Create(fol_And(), NULL);
+  
+  for (Scan = Clauses; Scan != list_Nil(); Scan = list_Cdr(Scan)) {
+    TermList =  cnf_RemoveSkolemFunctions((CLAUSE) list_Car(Scan),
+					  &SkolToExVar, Vars);
+    Term = term_Create(fol_Or(), TermList);
+    FreeVars = fol_FreeVariables(Term);
+    if (!list_Empty(FreeVars)) {
+      FreeVarsCopy = term_CopyTermList(FreeVars);
+      list_Delete(FreeVars);
+      Term = fol_CreateQuantifier(fol_All(), FreeVarsCopy, list_List(Term));
+    }
+    term_RplacArgumentList(TopTerm, list_Cons(Term, term_ArgumentList(TopTerm)));
+  }
+  
+  VarScan = Vars;
+  First = TRUE;
+  
+  for (Scan = SkolToExVar; Scan != list_Nil(); Scan = list_Cdr(Scan)) {
+    if (list_Empty(list_Car(Scan))) {
+      if (term_TopSymbol(TopTerm) == fol_All())
+	term_RplacArgumentList(TopTerm, list_Cons(term_Create((SYMBOL) list_Car(VarScan), NULL),  
+						  term_ArgumentList(TopTerm)));
+      if (!First)
+	TopTerm = fol_CreateQuantifier(fol_All(),
+				       list_List(term_Create((SYMBOL) list_Car(VarScan), NULL)),
+				       list_List(TopTerm)); 
+    }
+    else {
+      LIST ExVarScan;
+      LIST ExVars = list_Nil();
+      for (ExVarScan = list_Car(Scan); ExVarScan != list_Nil();
+	  ExVarScan = list_Cdr(ExVarScan)) {
+	if (ExVars == list_Nil())
+	  ExVars = list_List(term_Create((SYMBOL) list_PairSecond((LIST) list_Car(ExVarScan)), NULL));
+	else
+	  ExVars = list_Cons(term_Create((SYMBOL) list_PairSecond((LIST) list_Car(ExVarScan)), NULL), ExVars);
+	list_PairFree((LIST) list_Car(ExVarScan));
+      }
+      list_Delete((LIST) list_Car(Scan));
+      list_Rplaca(Scan, NULL);
+
+      if (term_TopSymbol(TopTerm) == fol_Exist()) {
+	VarListTerm = (TERM) list_Car(term_ArgumentList(TopTerm));
+	term_RplacArgumentList(VarListTerm,
+			       list_Nconc(term_ArgumentList(VarListTerm),
+					  ExVars));
+      }
+      else
+	TopTerm = fol_CreateQuantifier(fol_Exist(), ExVars, list_List(TopTerm));
+      ExVars = list_Nil();
+
+      if (!First) 
+	TopTerm = fol_CreateQuantifier(fol_All(), 
+				       list_List(term_Create((SYMBOL) list_Car(VarScan), NULL)),
+				       list_List(TopTerm));
+    }
+    if (!First) 
+      VarScan = list_Cdr(VarScan);
+    else
+      First = FALSE;
+	
+  }
+  list_Delete(SkolToExVar);
+  list_Delete(Vars);
+
+  return TopTerm;
+}
+
+
+#ifdef OPTCHECK
+/* Currently unused */
+/*static */
+LIST cnf_CheckOptimizedSkolemization(LIST* AxClauses, LIST* ConClauses,
+				     TERM AxTerm, TERM ConTerm,
+				     LIST NonConClauses, LIST* SkolemPredicates,
+				     SHARED_INDEX ShIndex, BOOL result)
+/**********************************************************
+  EFFECT: Used to check the correctness of optimized skolemization
+***********************************************************/
+{
+  TERM DeSkolemizedAxOpt, DeSkolemizedConOpt, DeSkolemizedAx, DeSkolemizedCon;
+  TERM TopOpt, Top, ToProve;
+  LIST SkolemFunctions2;
+
+  if (*AxClauses != list_Nil()) {
+    DeSkolemizedAxOpt = cnf_DeSkolemFormula(*AxClauses);
+    if (*ConClauses != list_Nil()) {
+      DeSkolemizedConOpt = cnf_DeSkolemFormula(*ConClauses);
+      TopOpt = term_Create(fol_And(), 
+			   list_Cons(DeSkolemizedAxOpt, 
+				     list_List(DeSkolemizedConOpt)));
+    }
+    else 
+      TopOpt = DeSkolemizedAxOpt;
+  }
+  else {
+    DeSkolemizedConOpt = cnf_DeSkolemFormula(*ConClauses);     
+    TopOpt = DeSkolemizedConOpt;
+  }
+  
+  clause_DeleteClauseList(*AxClauses);
+  clause_DeleteClauseList(*ConClauses);
+  *AxClauses = list_Nil();
+  *ConClauses = list_Nil();
+  
+  flag_SetFlagValue(flag_CNFOPTSKOLEM, flag_CNFOPTSKOLEMOFF);  
+  if (AxTerm) {
+    *AxClauses = cnf_OptimizedSkolemization(term_Copy(AxTerm), ShIndex, NonConClauses, result,FALSE, ClauseToTermLabellist);
+  }
+  if (ConTerm) {
+    *ConClauses = cnf_OptimizedSkolemization(term_Copy(ConTerm), ShIndex, NonConClauses, result,TRUE, ClauseToTermLabellist);
+  }
+  
+  if (*AxClauses != list_Nil()) {
+    DeSkolemizedAx = cnf_DeSkolemFormula(*AxClauses);
+    if (*ConClauses != list_Nil()) {
+      DeSkolemizedCon = cnf_DeSkolemFormula(*ConClauses);
+      Top = term_Create(fol_And(), 
+			list_Cons(DeSkolemizedAx, 
+				  list_List(DeSkolemizedCon)));
+    }
+    else 
+      Top = DeSkolemizedAx;
+  }
+  else {
+    DeSkolemizedCon = cnf_DeSkolemFormula(*ConClauses);    
+    Top = DeSkolemizedCon;
+  }
+  
+  clause_DeleteClauseList(*AxClauses);
+  clause_DeleteClausList(*ConClauses);
+  *AxClauses = list_Nil();
+  *ConClauses = list_Nil();
+  
+  ToProve = term_Create(fol_Equiv(), list_Cons(TopOpt, list_List(Top)));
+  ToProve = term_Create(fol_Not(), list_List(ToProve));
+  fol_NormalizeVars(ToProve); 
+  ToProve  = cnf_ObviousSimplifications(ToProve);
+  term_AddFatherLinks(ToProve);
+  ToProve  = ren_Rename(ToProve,SkolemPredicates,FALSE);
+  ToProve  = cnf_RemoveEquivImplFromFormula(ToProve);
+  ToProve  = cnf_NegationNormalFormula(ToProve);
+  ToProve  = cnf_AntiPrenex(ToProve);
+  
+  SkolemFunctions2 = list_Nil();
+  ToProve     = cnf_SkolemFormula(ToProve, &SkolemFunctions2);
+  ToProve     = cnf_DistributiveFormula(ToProve);
+  *ConClauses = cnf_MakeClauseList(ToProve);
+  if (ToProve)
+    term_Delete(ToProve);
+  *AxClauses = list_Nil();
+  return SkolemFunctions2;
+}
+#endif
+
+
+PROOFSEARCH cnf_Flotter(LIST AxiomList, LIST ConjectureList, LIST* AxClauses, 
+			LIST* AllLabels, HASH TermLabelToClauselist, 
+			HASH ClauseToTermLabellist, FLAGSTORE InputFlags,
+			PRECEDENCE InputPrecedence, LIST* Symblist)
+/**************************************************************
+  INPUT:   A list of axiom formulae,
+           a list of conjecture formulae,
+	   a pointer to a list in which clauses derived from axiom formulae 
+	   are stored,
+	   a pointer to a list in which clauses derived from 
+	   conjecture formulae are stored, ???
+	   a pointer to a list of all termlabels,
+	   a hasharray in which for every term label the list of clauses 
+	   derived from the term is stored (if DocProof is set),
+	   a hasharray in which for every clause the list of labels 
+	   of the terms used for deriving the clause is stored (if DocProof 
+	   is set),
+	   a flag store,
+	   a precedence
+	   a pointer to a list of symbols which have to be deleted later if
+	   the ProofSearch object is kept.
+  RETURNS: If KeepProofSearch ??? is TRUE, then the ProofSearch object is not
+           freed but returned.
+	   Else, NULL is returned.
+  EFFECT:  ??? EK
+           The precedence of new skolem symbols is set in <InputPrecedence>.
+***************************************************************/
+{
+  LIST        Scan, Scan2, FormulaClauses,SkolemFunctions;
+  LIST        SkolemPredicates, EmptyClauses, AllFormulae;
+  LIST        UsedTerms;
+  TERM        AxTerm,Formula;
+  BOOL        Result;
+  PROOFSEARCH Search;
+  PRECEDENCE  Precedence;
+  FLAGSTORE   Flags;
+  NAT         Count;
+  HASH        InputClauseToTermLabellist;
+
+  Search = prfs_Create();
+
+  /* Initialize the flagstore for the CNF transformation */
+  Flags = prfs_Store(Search);
+  flag_CleanStore(Flags);
+  flag_InitFlotterFlags(InputFlags, Flags);
+  /* Initialize the precedence */
+  Precedence = prfs_Precedence(Search);
+  symbol_TransferPrecedence(InputPrecedence, Precedence);
+
+  if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+    prfs_AddDocProofSharingIndex(Search);
+
+  AxTerm           = (TERM)NULL;
+  SkolemPredicates = list_Nil();
+  Result           = FALSE;
+  if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+    InputClauseToTermLabellist = hsh_Create();
+  else 
+    InputClauseToTermLabellist = NULL;
+
+  symbol_ReinitGenericNameCounters();
+
+  for (Scan = AxiomList; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    LIST Pair;
+    Pair = list_Car(Scan);
+    AxTerm = (TERM) list_PairSecond(Pair);
+    fol_RemoveImplied(AxTerm);
+    term_AddFatherLinks(AxTerm);
+    fol_NormalizeVars(AxTerm);
+    if (flag_GetFlagValue(Flags, flag_CNFFEQREDUCTIONS))
+      cnf_PropagateSubstEquations(AxTerm);
+    AxTerm = cnf_ObviousSimplifications(AxTerm);
+    if (flag_GetFlagValue(Flags, flag_CNFRENAMING)) {
+      term_AddFatherLinks(AxTerm);
+      AxTerm = ren_Rename(AxTerm, Precedence, &SkolemPredicates,
+			  flag_GetFlagValue(Flags, flag_CNFPRENAMING), TRUE);
+    }
+    AxTerm = cnf_RemoveEquivImplFromFormula(AxTerm);
+    AxTerm = cnf_NegationNormalFormula(AxTerm);
+    AxTerm = cnf_AntiPrenex(AxTerm);
+    list_Rplacd(Pair, (LIST) AxTerm);
+  }
+  AllFormulae = AxiomList;
+  
+  /* At this point the list contains max. 1 element, which is a pair 
+     of the label NULL and the negated
+     conjunction of all conjecture formulae. */
+
+  Count = 0;
+  for (Scan = ConjectureList; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    TERM  ConTerm;
+    char* Label;
+    char  buf[100];
+    /* Add label */  
+    if (list_PairFirst(list_Car(Scan)) == NULL) {
+      sprintf(buf, "conjecture%d", Count);
+      Label = string_StringCopy(buf);
+      list_Rplaca((LIST) list_Car(Scan), Label);
+      if (flag_GetFlagValue(Flags, flag_DOCPROOF) &&
+	  flag_GetFlagValue(Flags, flag_PLABELS)) {
+	printf("\nAdded label %s for conjecture", Label);
+	fol_PrettyPrintDFG((TERM) list_PairSecond(list_Car(Scan)));
+      }
+    }
+
+    ConTerm = (TERM) list_PairSecond((LIST) list_Car(Scan));
+    fol_RemoveImplied(ConTerm);
+    term_AddFatherLinks(ConTerm);
+    fol_NormalizeVars(ConTerm);  
+    if (flag_GetFlagValue(Flags, flag_CNFFEQREDUCTIONS))
+      cnf_PropagateSubstEquations(ConTerm);
+    ConTerm  = cnf_ObviousSimplifications(ConTerm); 
+
+    if (flag_GetFlagValue(Flags, flag_CNFRENAMING)) {
+      term_AddFatherLinks(ConTerm);
+      ConTerm = ren_Rename(ConTerm, Precedence, &SkolemPredicates,
+			   flag_GetFlagValue(Flags, flag_CNFPRENAMING),TRUE);
+    }
+    /* fputs("\nRen:\t",stdout);term_Print(ConTerm);putchar('\n'); */
+    ConTerm  = cnf_RemoveEquivImplFromFormula(ConTerm);
+    ConTerm  = cnf_NegationNormalFormula(ConTerm);
+    /* fputs("\nAn:\t",stdout);term_Print(ConTerm);putchar('\n'); */
+    ConTerm  = cnf_AntiPrenex(ConTerm);
+    /* fputs("\nPr:\t",stdout);term_Print(ConTerm);putchar('\n'); */
+    /* Insert changed term into pair */
+    list_Rplacd((LIST) list_Car(Scan), (LIST) ConTerm);
+
+    Count++;
+  } 
+
+  AllFormulae = list_Append(ConjectureList, AllFormulae);
+  for (Scan = ConjectureList;!list_Empty(Scan); Scan = list_Cdr(Scan))
+    list_Rplaca(Scan,list_PairSecond(list_Car(Scan)));
+
+  FormulaClauses = list_Nil();
+  SkolemFunctions = list_Nil();
+  Count = 0;
+  for (Scan = AllFormulae; !list_Empty(Scan); Scan = list_Cdr(Scan), Count++) {
+    LIST FormulaClausesTemp;
+    Formula            = term_Copy((TERM) list_PairSecond(list_Car(Scan)));
+#ifdef CHECK_CNF
+    fputs("\nInputFormula : ",stdout); term_Print(Formula); 
+    printf("\nLabel : %s", (char*) list_PairFirst(list_Car(Scan)));
+#endif
+    Formula            = cnf_SkolemFormula(Formula,Precedence,&SkolemFunctions);
+    Formula            = cnf_DistributiveFormula(Formula);
+    FormulaClausesTemp = cnf_MakeClauseList(Formula,FALSE,FALSE,Flags,Precedence);
+    if (flag_GetFlagValue(Flags, flag_DOCPROOF)) {
+      for (Scan2 = FormulaClausesTemp; !list_Empty(Scan2); Scan2 = list_Cdr(Scan2)) {
+	hsh_Put(InputClauseToTermLabellist, list_Car(Scan2), list_PairFirst(list_Car(Scan)));
+      }
+    }
+    FormulaClauses = list_Nconc(FormulaClauses, FormulaClausesTemp);
+    term_Delete(Formula);
+  }
+
+  /* Trage nun Formula Clauses modulo Reduktion in einen Index ein */
+ 
+  /* red_SatUnit works only on conclauses */
+  for (Scan = FormulaClauses; !list_Empty(Scan); Scan = list_Cdr(Scan))
+    clause_SetFlag((CLAUSE) list_Car(Scan), CONCLAUSE);
+  /* For FormulaClauses a full saturation */
+  /* List is deleted in red_SatUnit ! */
+  EmptyClauses = red_SatUnit(Search, FormulaClauses);
+  if (!list_Empty(EmptyClauses)) {
+    Result = TRUE;
+    /*puts("\nPROOF in FormulaClauses");*/
+    clause_DeleteClauseList(EmptyClauses);
+  }
+
+  /* Move all usables to workedoff */
+  FormulaClauses = list_Copy(prfs_UsableClauses(Search));
+  for (Scan = FormulaClauses; !list_Empty(Scan); Scan = list_Cdr(Scan))
+    prfs_MoveUsableWorkedOff(Search, (CLAUSE) list_Car(Scan));
+  list_Delete(FormulaClauses);
+  FormulaClauses = list_Nil();
+
+#ifdef CHECK
+  /*cnf_CheckClauseListsConsistency(ShIndex); */
+#endif     
+
+
+  *Symblist = list_Nil();
+  for (Scan = AllFormulae; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    LIST Ax, Pair;
+    UsedTerms = list_Nil();
+    Pair = list_Car(Scan);
+#ifdef CHECK_CNF
+    fputs("\nFormula : ", stdout);
+    term_Print((TERM) list_PairSecond(Pair)); 
+    printf("\nLabel : %s", (char*) list_PairFirst(Pair)); 
+#endif
+    Ax = cnf_OptimizedSkolemization(Search, term_Copy((TERM)list_PairSecond(Pair)), 
+				    (char*) list_PairFirst(Pair), &UsedTerms, 
+				    Symblist,Result,FALSE,InputClauseToTermLabellist);
+    /* Set CONCLAUSE flag for clauses derived from conjectures */
+    if (list_PointerMember(ConjectureList,list_PairSecond(Pair))) {
+      LIST l;
+      for (l = Ax; !list_Empty(l); l = list_Cdr(l))
+	clause_SetFlag((CLAUSE) list_Car(l), CONCLAUSE);
+    }
+    if (flag_GetFlagValue(Flags, flag_DOCPROOF)) {
+      hsh_PutListWithCompareFunc(TermLabelToClauselist, list_PairFirst(Pair),
+				 list_Copy(Ax),
+				 (BOOL (*)(POINTER,POINTER))cnf_LabelEqual,
+				 (unsigned long (*)(POINTER))hsh_StringHashKey);
+      UsedTerms = list_Cons(list_PairFirst(Pair), UsedTerms);
+      UsedTerms = cnf_DeleteDuplicateLabelsFromList(UsedTerms);
+      for (Scan2 = Ax; !list_Empty(Scan2); Scan2 = list_Cdr(Scan2)) {
+	hsh_PutList(ClauseToTermLabellist, list_Car(Scan2), list_Copy(UsedTerms));
+	hsh_PutList(InputClauseToTermLabellist, list_Car(Scan2), list_Copy(UsedTerms));
+      } 
+    }
+    *AxClauses = list_Nconc(*AxClauses, Ax);
+    list_Delete(UsedTerms);
+  }
+
+  /* Transfer precedence of new skolem symbols into <InputPrecedence> */
+  symbol_TransferPrecedence(Precedence, InputPrecedence);
+
+  list_Delete(ConjectureList);
+  if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+    hsh_Delete(InputClauseToTermLabellist);
+  if (!flag_GetFlagValue(Flags, flag_INTERACTIVE)) { 
+    list_Delete(*Symblist);
+  }
+
+  *AllLabels = list_Nil();
+  for (Scan = AllFormulae; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    LIST Pair;
+    Pair = list_Car(Scan);
+    term_Delete((TERM) list_PairSecond(Pair));
+    *AllLabels = list_Cons(list_PairFirst(Pair), *AllLabels);
+    list_PairFree(Pair);
+  }
+
+  list_Delete(AllFormulae);
+  list_Delete(SkolemFunctions);
+  list_Delete(SkolemPredicates);
+
+  if (!flag_GetFlagValue(Flags, flag_INTERACTIVE)) {
+    symbol_ResetSkolemIndex();
+    prfs_Delete(Search);
+    return NULL;
+  }
+  else {
+    /* Delete DocProof clauses */
+    prfs_DeleteDocProof(Search);
+    return Search;
+  }
+}
+
+LIST cnf_QueryFlotter(PROOFSEARCH Search, TERM Term, LIST* Symblist)
+/**************************************************************
+  INPUT:   A term to derive clauses from, using optimized skolemization,
+           and a ProofSearch object. 
+  RETURNS: A list of derived clauses.
+  EFFECT:  ??? EK
+           The precedence of new skolem symbols is set in <Search>.
+***************************************************************/
+{
+  LIST       SkolemPredicates, SkolemFunctions, IndexedClauses, Scan;
+  LIST       ResultClauses, Dummy, EmptyClauses;
+  TERM       TermCopy;
+  int        Formulae2Clause;
+  BOOL       Result;
+  FLAGSTORE  Flags, SubProofFlags;
+  PRECEDENCE Precedence;
+
+  Flags      = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+
+  /* Initialize the flagstore of the cnf_SEARCHCOPY object with default values */
+  /* and copy the value of flag_DOCPROOF from the global Proofserach object.   */
+  SubProofFlags = prfs_Store(cnf_SEARCHCOPY);
+  flag_InitStoreByDefaults(SubProofFlags);
+  flag_TransferFlag(Flags, SubProofFlags, flag_DOCPROOF);
+  /* Transfer the precedence into the local search object */
+  symbol_TransferPrecedence(Precedence, prfs_Precedence(cnf_SEARCHCOPY));
+
+  SkolemPredicates = SkolemFunctions = list_Nil();
+  Result = FALSE;
+  
+  prfs_CopyIndices(Search, cnf_SEARCHCOPY);
+
+  Term = term_Create(fol_Not(), list_List(Term));
+  fol_NormalizeVars(Term);
+  Term = cnf_ObviousSimplifications(Term);
+  if (flag_GetFlagValue(Flags, flag_CNFRENAMING)) {
+    term_AddFatherLinks(Term);
+    Term = ren_Rename(Term, Precedence, &SkolemPredicates,
+		      flag_GetFlagValue(Flags,flag_CNFPRENAMING), TRUE);
+  }
+  Term = cnf_RemoveEquivImplFromFormula(Term);
+  Term = cnf_NegationNormalFormula(Term);
+  Term = cnf_AntiPrenex(Term);
+  
+  TermCopy = term_Copy(Term);
+  TermCopy = cnf_SkolemFormula(TermCopy, Precedence, &SkolemFunctions);
+  TermCopy = cnf_DistributiveFormula(TermCopy);
+
+  IndexedClauses = cnf_MakeClauseList(TermCopy,FALSE,FALSE,Flags,Precedence);
+  term_Delete(TermCopy);
+
+  /* red_SatUnit works only on conclauses */
+  for (Scan = IndexedClauses; !list_Empty(Scan); Scan = list_Cdr(Scan))
+    clause_SetFlag((CLAUSE) list_Car(Scan), CONCLAUSE);
+
+  EmptyClauses = red_SatUnit(cnf_SEARCHCOPY, IndexedClauses);
+
+  if (!list_Empty(EmptyClauses)) {
+    Result = TRUE;
+    clause_DeleteClauseList(EmptyClauses);
+  }
+
+  while (!list_Empty(prfs_UsableClauses(cnf_SEARCHCOPY))) {
+    prfs_MoveUsableWorkedOff(cnf_SEARCHCOPY, (CLAUSE) list_Car(prfs_UsableClauses(cnf_SEARCHCOPY)));
+  }
+  /* Works only if DOCPROOF is false. Otherwise we need labels */
+  Dummy = list_Nil();
+  if (flag_GetFlagValue(SubProofFlags, flag_DOCPROOF))
+    Formulae2Clause = TRUE;
+  else
+    Formulae2Clause = FALSE;
+  flag_SetFlagValue(SubProofFlags, flag_DOCPROOF, flag_DOCPROOFOFF);
+  ResultClauses = cnf_OptimizedSkolemization(cnf_SEARCHCOPY, term_Copy(Term),
+					     NULL, &Dummy, Symblist, Result,
+					     FALSE, NULL);
+
+  if (Formulae2Clause)
+    flag_SetFlagValue(SubProofFlags, flag_DOCPROOF, flag_DOCPROOFON);
+  
+  term_Delete(Term);
+  list_Delete(SkolemPredicates);
+  list_Delete(SkolemFunctions);
+  prfs_Clean(cnf_SEARCHCOPY);
+
+  /* All result clauses of queries are conjecture clauses */
+  for (Scan=ResultClauses; !list_Empty(Scan); Scan=list_Cdr(Scan))
+    clause_SetFlag((CLAUSE) list_Car(Scan), CONCLAUSE);
+
+  return ResultClauses;
+}
+
+
+#ifdef CHECK
+/* Currently unused */
+/*static*/ void cnf_CheckClauseListsConsistency(SHARED_INDEX ShIndex)
+/**************************************************************
+  INPUT: A shared index and a list of non-ConClauses.
+  EFFECT: When this function is called all clauses in the index must be
+       non-ConClauses, which must also be members of the list.
+**************************************************************/
+{
+  LIST AllClauses, scan;
+
+  AllClauses = clause_AllIndexedClauses(ShIndex);
+  for (scan = AllClauses; scan != list_Nil(); scan = list_Cdr(scan)) {
+    if (clause_GetFlag((CLAUSE) list_Car(scan), CONCLAUSE)) {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In cnf_CheckClauseListsConsistency: Clause is a CONCLAUSE.\n");
+      misc_FinishErrorReport();
+    } 
+    if (clause_GetFlag((CLAUSE) list_Car(scan), BLOCKED)) {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In cnf_CheckClauseListsConsistency: Clause is BLOCKED.\n");
+      misc_FinishErrorReport();
+    }
+  }
+  list_Delete(AllClauses);
+}
+#endif
+
+
+static LIST cnf_SatUnit(PROOFSEARCH Search, LIST ClauseList) 
+/*********************************************************
+  INPUT:   A list of unshared clauses, proof search object
+  RETURNS: A possibly empty list of empty clauses.
+**********************************************************/
+{
+  CLAUSE     Given;
+  LIST       Scan, Derivables, EmptyClauses, BackReduced;
+  NAT        n, Derived;
+  FLAGSTORE  Flags;
+  PRECEDENCE Precedence;
+
+  Flags        = prfs_Store(Search);
+  Precedence   = prfs_Precedence(Search);
+  Derived      = flag_GetFlagValue(Flags, flag_CNFPROOFSTEPS);
+  EmptyClauses = list_Nil();
+  ClauseList   = clause_ListSortWeighed(ClauseList);
+  
+  while (!list_Empty(ClauseList) && list_Empty(EmptyClauses)) {
+    Given = (CLAUSE)list_NCar(&ClauseList);
+    Given = red_CompleteReductionOnDerivedClause(Search, Given, red_ALL);
+    if (Given) {
+      if (clause_IsEmptyClause(Given))
+        EmptyClauses = list_List(Given);
+      else {
+        /*fputs("\n\nGiven: ",stdout);clause_Print(Given);*/
+	BackReduced = red_BackReduction(Search, Given, red_USABLE);
+	
+        if (Derived != 0) {
+	  Derivables =
+	    inf_BoundedDepthUnitResolution(Given, prfs_UsableSharingIndex(Search),
+					   FALSE, Flags, Precedence);
+	  Derivables =
+	    list_Nconc(Derivables,
+		       inf_BoundedDepthUnitResolution(Given,prfs_WorkedOffSharingIndex(Search),
+						      FALSE, Flags, Precedence));
+          n = list_Length(Derivables);
+          if (n > Derived)
+            Derived = 0;
+          else
+            Derived -= n;
+        }
+        else 
+          Derivables = list_Nil();
+	
+        Derivables  = list_Nconc(BackReduced,Derivables);
+        Derivables  = split_ExtractEmptyClauses(Derivables, &EmptyClauses);
+	
+	prfs_InsertUsableClause(Search, Given);
+	
+	for (Scan = Derivables; !list_Empty(Scan); Scan = list_Cdr(Scan))
+	  ClauseList = clause_InsertWeighed(list_Car(Scan), ClauseList, Flags,
+					    Precedence);
+	list_Delete(Derivables);
+      }
+    }
+  }
+  clause_DeleteClauseList(ClauseList);
+  return EmptyClauses;
+}
+
+
+TERM cnf_DefTargetConvert(TERM Target, TERM ToTopLevel, TERM ToProveDef, 
+			  LIST DefPredArgs, LIST TargetPredArgs,
+			  LIST TargetPredVars, LIST VarsForTopLevel,
+			  FLAGSTORE Flags, PRECEDENCE Precedence,
+			  BOOL* LocallyTrue)
+/**********************************************************
+  INPUT:   A term Target which contains a predicate that might be replaced
+           by its definition.
+	   A term ToTopLevel which is the highest level subterm in Target
+	   that contains the predicate and can be moved to top level or().
+	   A term ToProveDef which must hold if the definition is to be applied.
+	   (IS DESTROYED AND FREED)
+	   A list DefPredArgs of the arguments of the predicate in the
+	   Definition.
+	   A list TargetPredArgs of the arguments of the predicate in Target.
+	   A list TargetPredVars of the variables occurring in the arguments
+	   of the predicate in Target.
+	   A list VarsForTopLevel containing the variables that should be
+	   all-quantified at top level to make the proof easier.
+	   A flag store.
+	   A pointer to a boolean LocallyTrue which is set to TRUE iff
+	   the definition can be applied.
+  RETURNS: The Target term which is brought into standard form.
+**********************************************************/
+
+{
+  TERM orterm, targettoprove;
+  SYMBOL maxvar;                    /* For normalizing terms */
+  LIST l1, l2;
+  LIST freevars, vars;              /* Free variables in targettoprove */
+
+  if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) {
+    puts("\nTarget :");
+    fol_PrettyPrint(Target);
+  }
+#ifdef CHECK
+  fol_CheckFatherLinks(Target);
+#endif
+  /* No proof found yet */
+  *LocallyTrue = FALSE;
+
+  /* Remove implications from path */
+  Target = cnf_RemoveImplFromFormulaPath(Target, ToTopLevel);
+    
+  /* Move negations as far down as possible */
+  Target = cnf_NegationNormalFormulaPath(Target, ToTopLevel);
+    
+  /* Move quantifiers as far down as possible */
+  Target = cnf_AntiPrenexPath(Target, ToTopLevel);
+
+  /* Move all-quantified variables from the predicates' arguments to top level */
+  Target = cnf_MovePredicateVariablesUp(Target, ToTopLevel, VarsForTopLevel);
+
+  /* Flatten top or() */
+  Target = cnf_FlattenPath(Target, ToTopLevel);
+
+  /* Now make sure that all variables in the top forall quantifier are in TargetPredVars */
+  /* Not necessary, according to CW */
+  if (symbol_Equal(term_TopSymbol(Target), fol_All())) {
+    targettoprove = term_Copy(term_SecondArgument(Target));
+    orterm        = term_SecondArgument(Target);
+  }
+  else {
+    targettoprove = term_Copy(Target);
+    orterm        = Target;
+  }
+
+  /* Find argument of targettoprove that contains the predicate and remove it */
+  if (symbol_Equal(term_TopSymbol(targettoprove), fol_Or())) {
+    /* Find subterm that contains the predicate */
+    LIST arglist;
+    arglist = term_ArgumentList(targettoprove);
+    for (l1=arglist, l2=term_ArgumentList(orterm); !list_Empty(l1); 
+	l1 = list_Cdr(l1), l2 = list_Cdr(l2)) {
+      if (term_HasProperSuperterm(ToTopLevel, (TERM) list_Car(l2)) ||
+	  (ToTopLevel == (TERM) list_Car(l2))) {
+	arglist = list_PointerDeleteElementFree(arglist, list_Car(l1),
+						(void (*)(POINTER))term_Delete);
+	break;
+      }
+    }
+    term_RplacArgumentList(targettoprove, arglist);
+    /* Nothing left for the proof ? */
+    if (list_Empty(term_ArgumentList(targettoprove))) {
+      term_Delete(targettoprove);
+      term_Delete(ToProveDef);
+#ifdef CHECK
+      fol_CheckFatherLinks(Target);
+#endif
+      return Target;
+    }
+  }
+  else {
+    /* Nothing left for the proof */
+    term_Delete(targettoprove);
+    term_Delete(ToProveDef);
+#ifdef CHECK
+    fol_CheckFatherLinks(Target);
+#endif
+    return Target;
+  }
+
+  /* Normalize variables in ToProveDef with respect to targettoprove */
+  maxvar = term_MaxVar(targettoprove);
+  symbol_SetStandardVarCounter(maxvar);
+  vars = fol_BoundVariables(ToProveDef);
+  vars = term_DeleteDuplicatesFromList(vars);
+  for (l1=vars; !list_Empty(l1); l1=list_Cdr(l1))
+    term_ExchangeVariable(ToProveDef, term_TopSymbol(list_Car(l1)), symbol_CreateStandardVariable());
+  list_Delete(vars);
+  
+  /* Replace arguments of predicate in condition of definition by matching arguments
+     of predicate in target term */
+  for (l1=DefPredArgs, l2=TargetPredArgs; !list_Empty(l1); l1=list_Cdr(l1), l2=list_Cdr(l2)) 
+    term_ReplaceVariable(ToProveDef, term_TopSymbol((TERM) list_Car(l1)), (TERM) list_Car(l2));
+
+  targettoprove = term_Create(fol_Not(), list_List(targettoprove));
+  targettoprove = cnf_NegationNormalFormula(targettoprove);
+  targettoprove = term_Create(fol_Implies(), 
+			      list_Cons(targettoprove, list_List(ToProveDef)));
+
+  /* At this point ToProveDef must not be accessed again ! */
+  
+  /* Add all--quantifier to targettoprove */
+  freevars = fol_FreeVariables(targettoprove);
+  term_CopyTermsInList(freevars);
+  targettoprove = fol_CreateQuantifier(fol_All(), freevars, list_List(targettoprove));
+  
+  if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) {
+    puts("\nConverted to :");
+    fol_PrettyPrint(Target);
+  }
+
+  targettoprove = cnf_NegationNormalFormula(targettoprove);
+  
+  if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) {
+    puts("\nToProve for this target :");
+    fol_PrettyPrint(targettoprove);
+  }
+ 
+  *LocallyTrue = cnf_HaveProof(list_Nil(), targettoprove, Flags, Precedence);
+  
+  term_Delete(targettoprove);
+
+#ifdef CHECK
+  fol_CheckFatherLinks(Target);
+#endif
+
+  return Target;
+}
+
+
+static TERM cnf_RemoveQuantFromPathAndFlatten(TERM TopTerm, TERM SubTerm)
+/**********************************************************
+  INPUT:  Two terms, <SubTerm> must be a subterm of <TopTerm>.
+          Superterm of <SubTerm> must be an equivalence.
+	  Along the path to SubTerm there are only quantifiers or disjunctions.
+	  All free variables in the equivalence are free variables
+	  in <SubTerm>.
+	  All free variables in <SubTerm> are bound by a universal quantifier
+	  (with polarity 1).
+  RETURN: The destructively changed <TopTerm>.
+  EFFECT: Removes all quantifiers not binding a variable in <SubTerm>
+          from <subTerm>'s path.
+          Moves all universal quantifiers binding free variable
+	  in <SubTerm> up.
+	  <TopTerm> is transformed into the form
+	  forall([X1,...,Xn],or (equiv(<SubTerm>,psi),phi)).
+**********************************************************/
+{
+  TERM Term1, Term2, Flat, Variable;
+  LIST Scan1, Scan2, FreeVars;
+
+
+#ifdef CHECK
+  if (!fol_CheckFormula(TopTerm) || !term_HasPointerSubterm(TopTerm, SubTerm)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\nIn cnf_RemoveQuantFromPathAndFlatten: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  TopTerm = cnf_SimplifyQuantors(TopTerm);
+  term_AddFatherLinks(TopTerm);
+  Term1   = term_Superterm(SubTerm);
+
+  while (Term1 != TopTerm) {
+
+    while (symbol_Equal(fol_Or(), term_TopSymbol(Term1)) && (TopTerm != Term1)) {
+      Term1 = term_Superterm(Term1);
+    }
+    if (fol_IsQuantifier(term_TopSymbol(Term1))) {
+      Flat  = term_SecondArgument(Term1);
+      Flat  = cnf_Flatten(Flat, fol_Or());
+      Scan1 = fol_QuantifierVariables(Term1);
+      while (!list_Empty(Scan1)) {
+	Variable = (TERM)list_Car(Scan1);
+	if (fol_VarOccursFreely(Variable, SubTerm)) {
+	  Scan2 = list_Cdr(Scan1);
+	  fol_DeleteQuantifierVariable(Term1, term_TopSymbol(list_Car(Scan1)));
+	  Scan1 = Scan2;
+	}
+	else {
+	  Scan1 = list_Cdr(Scan1);
+	}
+      }
+      if (fol_IsQuantifier(term_TopSymbol(Term1))) {
+	/* still variables, but not binding a variable in the equivalence term */
+	LIST ArgList;
+
+	term_RplacArgumentList(Flat, list_PointerDeleteOneElement(term_ArgumentList(Flat), SubTerm));
+	ArgList = term_ArgumentList(Term1);
+       	term_RplacArgumentList(Term1, list_Nil());
+	Term2 = term_Create(term_TopSymbol(Term1), ArgList);
+	term_RplacArgumentList(Term1, list_Cons(SubTerm, list_List(Term2)));
+	term_RplacTop(Term1, fol_Or());
+	Scan1 = term_ArgumentList(Term1); 
+	while (!list_Empty(Scan1)) {
+	  term_RplacSuperterm((TERM)list_Car(Scan1), Term1);
+	  Scan1 = list_Cdr(Scan1);
+	}
+      }
+    }
+    else {
+
+#ifdef CHECK
+      if (!symbol_Equal(term_TopSymbol(Term1), fol_Or())) {
+	misc_StartErrorReport();
+	misc_ErrorReport("\nIn cnf_RemoveQuantFromPathAndFlatten: Illegal term Term1");
+	misc_FinishErrorReport();
+      }
+#endif
+
+      Term1 = cnf_Flatten(Term1, fol_Or());
+    }
+  }
+  FreeVars = fol_FreeVariables(Term1);
+  if (!list_Empty(FreeVars)) {
+    term_CopyTermsInList(FreeVars);
+    TopTerm = fol_CreateQuantifier(fol_All(), FreeVars, list_List(Term1));
+  }
+  return TopTerm;
+}
+
+
+TERM cnf_DefConvert(TERM Def, TERM FoundPredicate, TERM* ToProve)
+/*********************************************************
+  INPUT:   A term Def which is an equivalence (P(x1,..,xn) <=> Formula)
+           that can be converted to standard form.
+           The subterm that holds the defined predicate.
+           A pointer to a term ToProve into which a term is stored
+	   that has to be proved before applying the definition.
+  RETURNS: The converted definition : forall([..], or(equiv(..,..), ..))
+************************************************************/
+{
+  TERM orterm;
+
+#ifdef CHECK
+  fol_CheckFatherLinks(Def);
+#endif
+  
+  Def = cnf_RemoveImplFromFormulaPath(Def, FoundPredicate);   /* Remove implications along the path */
+  Def = cnf_NegationNormalFormulaPath(Def, FoundPredicate);   /* Move not's as far down as possible */
+
+#ifdef CHECK
+  if (!fol_CheckFormula(Def)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\nIn cnf_DefConvert: Illegal input Formula.\n");
+    misc_FinishErrorReport();
+  }
+  if (!term_HasPointerSubterm(Def, FoundPredicate)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\nIn cnf_DefConvert: Illegal input SubTerm.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Def = cnf_RemoveQuantFromPathAndFlatten(Def, term_Superterm(FoundPredicate));
+  term_AddFatherLinks(Def);
+
+#ifdef CHECK
+  if (!fol_CheckFormula(Def)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\nIn cnf_DefConvert: Illegal term Def.");
+    misc_FinishErrorReport();
+  }
+  if (!term_HasPointerSubterm(Def, FoundPredicate)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\nIn cnf_DefConvert: Illegal term FoundPredicate.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  /* Find top level or() */
+  if (symbol_Equal(term_TopSymbol(Def), fol_All())) {
+    /* Make sure there are several arguments */
+    if (symbol_Equal(term_TopSymbol(term_SecondArgument(Def)), fol_Or()) &&
+	(list_Length(term_ArgumentList(term_SecondArgument(Def))) == 1)) {
+      TERM t;
+      t = term_SecondArgument(Def);
+      term_RplacSecondArgument(Def, term_FirstArgument(term_SecondArgument(Def)));
+      term_Free(t);
+      orterm = NULL;
+      term_RplacSuperterm(term_SecondArgument(Def), Def);
+    }
+    else 
+      orterm = term_SecondArgument(Def);
+  }
+  else {
+    /* Make sure there are several arguments */
+    if (symbol_Equal(term_TopSymbol(Def), fol_Or()) &&
+	(list_Length(term_ArgumentList(Def)) == 1)) {
+      TERM t;
+      t = Def;
+      Def = term_FirstArgument(Def);
+      term_Free(t);
+      orterm = NULL;
+      term_RplacSuperterm(term_SecondArgument(Def), Def);
+    }
+    else 
+      orterm = Def;
+  }
+
+  /* If there is something to prove */
+  if (orterm != (TERM) NULL) {
+    TERM equiv;
+    LIST args;
+
+    equiv = (TERM) NULL;
+
+    /* In pell 10 there are no conditions for the equivalence */
+    if (symbol_Equal(term_TopSymbol(orterm), fol_Equiv())) {
+      equiv = orterm;
+      *ToProve = NULL;
+    }
+    else {
+      TERM t;
+      /* First find equivalence term among arguments */
+      args  = term_ArgumentList(orterm);
+      equiv = term_Superterm(FoundPredicate);
+      
+      /* Delete equivalence from list */
+      args = list_PointerDeleteElement(args, equiv);
+      term_RplacArgumentList(orterm, args);
+      
+      /* ToProve consists of all the definitions arguments except the equivalence */
+      *ToProve = term_Copy(orterm);
+      
+      /* Now not(*ToProve) implies the equivalence */
+      /* Negate *ToProve */
+      *ToProve = term_Create(fol_Not(), list_List(*ToProve));
+      *ToProve = cnf_NegationNormalFormula(*ToProve);
+      term_AddFatherLinks(*ToProve);
+
+      /* Now convert definition to implication form */
+      term_RplacTop(orterm, fol_Implies());
+      t = term_Create(fol_Not(), 
+		      list_List(term_Create(fol_Or(), 
+					    term_ArgumentList(orterm))));
+      term_RplacArgumentList(orterm, list_Cons(t, list_List(equiv)));
+
+      Def = cnf_NegationNormalFormula(Def);
+      term_AddFatherLinks(Def);
+    }    
+  }
+  
+#ifdef CHECK
+  fol_CheckFatherLinks(Def);
+#endif
+  return Def;
+}
+
+
+LIST cnf_HandleDefinition(PROOFSEARCH Search, LIST Pair, LIST Axioms,
+			  LIST Sorts, LIST Conjectures)
+/*******************************************************************
+  INPUT:   A PROOFSEARCH object, a pair (label, term) and 3 lists of pairs.
+           If the term in pair is a definition, the defined predicate
+	   is expanded in all the lists
+           and added to the proofsearch object.
+  RETURNS: The pair with the converted definition:
+           forall([..], or(equiv(..,..), .......))
+********************************************************************/
+{
+  TERM definition, defpredicate, equivterm;
+  
+  BOOL alwaysapplicable;     /* Is set to TRUE iff the definition can always be applied */
+  FLAGSTORE Flags;
+  PRECEDENCE Precedence;
+
+  Flags      = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+
+  /* The axiomlist consists of (label, formula) pairs */
+  definition = list_PairSecond(Pair);
+  
+  /* Test if Definition contains a definition */
+  defpredicate = (TERM) NULL;
+  if (cnf_ContainsDefinition(definition, &defpredicate)) { 
+    TERM toprove;
+    LIST allformulae, scan;
+
+    /* Create list of all formula pairs */
+    /* Check if definition may be applied to each formula */
+    allformulae = list_Copy(Axioms);
+    allformulae = list_Nconc(allformulae, list_Copy(Sorts));
+    allformulae = list_Nconc(allformulae, list_Copy(Conjectures));
+#ifdef CHECK
+    for (scan=allformulae; !list_Empty(scan); scan=list_Cdr(scan)) {
+      if (!list_Empty((LIST) list_Car(scan))) {
+	if (!term_IsTerm((TERM) list_PairSecond((LIST) list_Car(scan))))
+	  fol_CheckFatherLinks((TERM) list_PairSecond((LIST) list_Car(scan)));
+      }
+    }
+#endif
+    
+    /* Convert definition to standard form */
+    if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) {
+      fputs("\nPredicate : ", stdout);
+      symbol_Print(term_TopSymbol(defpredicate));
+    }
+
+    definition = cnf_DefConvert(definition, defpredicate, &toprove);
+    if (toprove == NULL)
+      alwaysapplicable = TRUE;
+    else 
+      alwaysapplicable = FALSE;
+
+    prfs_SetDefinitions(Search, list_Cons(term_Copy(definition), 
+					  prfs_Definitions(Search)));
+    
+    if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) {
+      if (alwaysapplicable) {
+	fputs("\nAlways Applicable     : ", stdout);
+	fol_PrettyPrint(definition); 
+      } 
+    }
+
+    /* Definition is converted to a form where the equivalence is
+       the first argument of the disjunction */
+    equivterm     = term_SecondArgument(term_Superterm(defpredicate));
+    
+    
+    scan = allformulae;
+    while (!list_Empty(scan)) {
+      BOOL localfound;
+      LIST pair, targettermvars;
+      
+      /* Pair label / term */
+      pair = list_Car(scan);
+
+      /* Pair may be NULL if it is a definition that could be deleted */
+      if ((pair != NULL) && (definition != (TERM) list_PairSecond(pair))) {
+	TERM target, targetpredicate, totoplevel;
+	LIST varsfortoplevel;
+	target = (TERM) list_PairSecond(pair);
+	targettermvars = varsfortoplevel = list_Nil();
+	
+	/* If definition is not always applicable, check if it is applicable
+	   for this formula */
+	localfound = FALSE;
+	if (!alwaysapplicable) {
+	  if (cnf_ContainsPredicate(target, term_TopSymbol(defpredicate),
+				    &targetpredicate, &totoplevel,
+				    &targettermvars, &varsfortoplevel)) {
+	    TERM toprovecopy;
+	    toprovecopy = term_Copy(toprove);
+	    target = cnf_DefTargetConvert(target, totoplevel, toprovecopy,
+					  term_ArgumentList(defpredicate),
+					  term_ArgumentList(targetpredicate),
+					  targettermvars, varsfortoplevel,
+					  Flags, Precedence, &localfound);
+	    list_Delete(targettermvars);
+	    list_Delete(varsfortoplevel);
+	    targettermvars = varsfortoplevel = list_Nil();
+	    
+	    list_Rplacd(pair, (LIST) target);
+	    if (localfound)
+	      list_Rplacd(pair, 
+			  (LIST) cnf_ApplyDefinitionOnce(defpredicate, 
+							 equivterm,
+							 list_PairSecond(pair),
+							 targetpredicate,
+							 Flags));
+	  }
+	}
+	else {
+	  if (cnf_ContainsPredicate(target, term_TopSymbol(defpredicate), 
+				    &targetpredicate, &totoplevel,
+				    &targettermvars, &varsfortoplevel))
+	    list_Rplacd(pair, (LIST) cnf_ApplyDefinitionOnce(defpredicate, 
+							     equivterm,
+							     list_PairSecond(pair),
+							     targetpredicate,
+							     Flags));
+	  else
+	    scan = list_Cdr(scan);
+	  list_Delete(targettermvars);
+	  list_Delete(varsfortoplevel);
+	  targettermvars = varsfortoplevel = list_Nil();
+	}
+      }
+      else
+	scan = list_Cdr(scan);
+    }
+    list_Delete(allformulae);
+    /* toprove can be NULL if the definition can always be applied */
+    if (toprove != (TERM) NULL)
+      term_Delete(toprove);
+    list_Rplacd(Pair, (LIST) definition);
+  }
+ 
+  return Pair;
+}
+
+
+LIST cnf_ApplyDefinitionToClause(CLAUSE Clause, TERM Predicate, TERM Expansion,
+				 FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, two terms and a flag store and a precedence.
+  RETURNS: The list of clauses where each occurrence of Predicate is 
+           replaced by Expansion.
+***************************************************************/
+{
+  NAT  i;
+  BOOL changed;
+  LIST args, scan, symblist;
+  TERM clauseterm, argument;
+
+  changed = FALSE;
+  
+  /* Build term from clause */
+  args = list_Nil();
+  for (i = 0; i < clause_Length(Clause); i++) {
+    argument = clause_GetLiteralTerm(Clause, i); /* with sign */
+    args     = list_Cons(term_Copy(argument), args);
+  }
+  clauseterm = term_Create(fol_Or(), args);
+
+  for (scan=term_ArgumentList(clauseterm); !list_Empty(scan); scan=list_Cdr(scan)) {
+    BOOL isneg;
+
+    argument = (TERM) list_Car(scan);
+    if (symbol_Equal(term_TopSymbol(argument), fol_Not())) {
+      argument = term_FirstArgument(argument);
+      isneg = TRUE;
+    }
+    else 
+      isneg = FALSE;
+      
+    /* Try to match with predicate */
+    cont_StartBinding();
+    if (unify_Match(cont_LeftContext(), Predicate, argument)) {
+      SUBST subst;
+      TERM  newargument;
+      subst = subst_ExtractMatcher();
+      newargument = subst_Apply(subst, term_Copy(Expansion));
+      subst_Free(subst);
+      if (isneg)
+	newargument = term_Create(fol_Not(), list_List(newargument));
+      term_Delete((TERM) list_Car(scan));
+      list_Rplaca(scan, newargument);
+      changed = TRUE;
+    }      
+    cont_BackTrack();
+  }
+
+  if (changed) {
+    /* Build term and derive list of clauses */
+    LIST result;
+    if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) {
+      puts("\nClause before applying def :");
+      clause_Print(Clause);
+      puts("\nPredicate :");
+      fol_PrettyPrint(Predicate);
+      puts("\nExpansion :");
+      fol_PrettyPrint(Expansion);
+    }
+    symblist   = list_Nil();
+    clauseterm = cnf_Cnf(clauseterm, Precedence, &symblist);
+    result     = cnf_MakeClauseList(clauseterm,FALSE,FALSE,Flags,Precedence);
+    list_Delete(symblist);
+    term_Delete(clauseterm);
+    if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) {
+      LIST l;
+      puts("\nClauses derived by expanding definition :");
+      for (l = result; !list_Empty(l); l=list_Cdr(l)) {
+	clause_Print((CLAUSE) list_Car(l));
+	fputs("\n", stdout);
+      }
+    }
+    return result;
+  }
+  else {
+    term_Delete(clauseterm);
+    return list_Nil();
+  }
+}
+
+
+BOOL cnf_PropagateSubstEquations(TERM StartTerm)
+/*************************************************************
+  INPUT:   A term where we assume that father links are established and
+           that no variable is bound by more than one quantifier.
+  RETURNS: TRUE, if any substitutions were made, FALSE otherwise.
+  EFFECT:  Function looks for equations of the form x=t where x does not
+           occur in t. If x=t occurs negatively and disjunctively below
+	   a universal quantifier binding x or if x=t occurs positively and
+	   conjunctively below an existential quantifier binding x,
+           all occurrences of  x are replaced by t in <StartTerm>.
+**************************************************************/
+{
+  LIST   Subequ;
+  TERM   QuantorTerm, Equation, EquationTerm;
+  SYMBOL Variable;
+  BOOL   Hit, Substituted;
+
+#ifdef CHECK
+  if (fol_VarBoundTwice(StartTerm)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cnf_PropagateSubstEquations: Variables of");
+    misc_ErrorReport("\n input term are not normalized.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Substituted = FALSE;
+
+  Subequ = fol_GetSubstEquations(StartTerm);
+  for ( ; !list_Empty(Subequ); Subequ = list_Pop(Subequ)) {
+    Hit          = FALSE;
+    Equation     = list_Car(Subequ);
+    Variable     = symbol_Null();
+    QuantorTerm  = term_Null();
+    EquationTerm = term_Null();
+
+    if (term_IsVariable(term_FirstArgument(Equation)) &&
+	!term_ContainsVariable(term_SecondArgument(Equation),
+			       term_TopSymbol(term_FirstArgument(Equation)))) {
+
+      Variable     = term_TopSymbol(term_FirstArgument(Equation));
+      QuantorTerm  = fol_GetBindingQuantifier(Equation, Variable);
+      EquationTerm = term_SecondArgument(Equation);
+      Hit          = fol_PolarCheck(Equation, QuantorTerm);
+    }
+    if (!Hit && term_IsVariable(term_SecondArgument(Equation)) &&
+	!term_ContainsVariable(term_FirstArgument(Equation),
+			       term_TopSymbol(term_SecondArgument(Equation)))) {
+
+      Variable     = term_TopSymbol(term_SecondArgument(Equation));
+      QuantorTerm  = fol_GetBindingQuantifier(Equation, Variable);
+      EquationTerm = term_FirstArgument(Equation);
+      Hit          = fol_PolarCheck(Equation, QuantorTerm);
+    }
+    if (Hit) {
+      fol_DeleteQuantifierVariable(QuantorTerm,Variable);
+      term_ReplaceVariable(StartTerm, Variable, EquationTerm); /* We replace everythere ! */
+      term_AddFatherLinks(StartTerm);
+      if (symbol_Equal(term_TopSymbol(QuantorTerm),fol_Equality())) /* Trivial Formula */
+	fol_SetTrue(QuantorTerm);
+      else
+	fol_SetTrue(Equation);
+      Substituted = TRUE;
+    }   
+  }
+
+  /* <Subequ> was freed in the loop. */
+
+  return Substituted;
+}
diff --git a/test/spass/cnf.h b/test/spass/cnf.h
new file mode 100644
index 0000000000000000000000000000000000000000..be04c5f67e0fb22ea5537ad6bcf199ef7d10341e
--- /dev/null
+++ b/test/spass/cnf.h
@@ -0,0 +1,120 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *               NAIVE CNF TRANSLATOR                     * */
+/* *                                                        * */
+/* *  $Module:   CNF                                        * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000            * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#ifndef _CNF_
+#define _CNF_
+
+#include "hasharray.h"
+#include "renaming.h"
+#include "resolution.h"
+#include "search.h"
+#include "flags.h"
+
+#include <string.h>
+
+/**************************************************************/
+/* Functions                                                 */
+/**************************************************************/
+
+static __inline__ BOOL cnf_LabelEqual(const char* l1, const char* l2)
+/********************************************************
+  INPUT:   Two labels.
+  RETURNS: TRUE, if the labels are equal, FALSE otherwise.
+*********************************************************/
+{
+  return string_Equal(l1, l2);
+}
+
+
+static __inline__ LIST cnf_DeleteDuplicateLabelsFromList(LIST Labels)
+/********************************************************
+  INPUT:   A list of labels.
+  RETURNS: The list where duplicate labels are removed.
+  EFFECTS: The duplicate labels are not freed.
+*********************************************************/
+{
+  return list_DeleteDuplicates(Labels, (BOOL (*)(POINTER,POINTER))cnf_LabelEqual);
+}
+
+
+TERM        cnf_ApplyDefinitionOnce(TERM, TERM, TERM, TERM, FLAGSTORE);
+LIST        cnf_ApplyDefinitionToClause(CLAUSE, TERM, TERM,FLAGSTORE,PRECEDENCE);
+
+BOOL        cnf_ContainsDefinition(TERM, TERM*);
+BOOL        cnf_ContainsPredicate(TERM, SYMBOL, TERM*, TERM*, LIST*, LIST*);
+
+TERM        cnf_DeSkolemFormula(LIST);
+TERM        cnf_DefConvert(TERM, TERM, TERM*);
+void        cnf_FilePrint(TERM, FILE*);
+TERM        cnf_DefTargetConvert(TERM, TERM, TERM, LIST, LIST, LIST, LIST,
+				 FLAGSTORE, PRECEDENCE, BOOL*);
+
+void        cnf_FilePrintPrefix(TERM, FILE*);
+void        cnf_FPrint(TERM, FILE*);
+TERM        cnf_Flatten(TERM, SYMBOL);
+PROOFSEARCH cnf_Flotter(LIST, LIST, LIST*, LIST*, HASH, HASH, FLAGSTORE,
+			PRECEDENCE, LIST*);
+void        cnf_Free(FLAGSTORE);
+
+LIST        cnf_HandleDefinition(PROOFSEARCH, LIST, LIST, LIST, LIST);
+void        cnf_Init(FLAGSTORE);
+TERM        cnf_NegationNormalFormula(TERM);
+TERM        cnf_ObviousSimplifications(TERM);
+
+LIST        cnf_QueryFlotter(PROOFSEARCH, TERM, LIST*);
+void        cnf_StdoutPrint(TERM);
+
+BOOL        cnf_PropagateSubstEquations(TERM);
+
+BOOL        cnf_HaveProof(LIST, TERM, FLAGSTORE, PRECEDENCE);
+
+
+#endif
diff --git a/test/spass/component.c b/test/spass/component.c
new file mode 100644
index 0000000000000000000000000000000000000000..def8e30cab803eddb992264221f32a89c61043c4
--- /dev/null
+++ b/test/spass/component.c
@@ -0,0 +1,266 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *               COMPONENTS OF CLAUSES                    * */
+/* *                                                        * */
+/* *  $Module:   COMPONENT                                  * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1998, 2000, 2001                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "term.h"
+#include "component.h"
+
+
+CLITERAL literal_Create(BOOL used, int index, LIST varlist) 
+/**********************************************************
+  INPUT:   A boolean used, an integer index and a list varlist.
+  RETURNS: A LITERAL is created.
+  MEMORY:  The boolean, integer and varlist are  no copies.
+*** ********************************************************/
+{ 
+  CLITERAL literal;
+
+  literal = (CLITERAL)memory_Malloc(sizeof(CLITERAL_NODE));
+  literal_PutUsed(literal,used);
+  literal_PutLitIndex(literal,index);
+  literal_PutLitVarList(literal,varlist);
+   
+  return literal;
+}
+
+
+void literal_Delete(CLITERAL literal) 
+/**********************************************************
+  INPUT:   A literal.
+  RETURNS: None.
+  MEMORY:   Deletes the LITERAL and frees the storage.
+***********************************************************/
+{ 
+  list_Delete(literal_GetLitVarList(literal)); 
+  literal_Free(literal);
+}
+
+
+LITPTR litptr_Create(LIST Indexlist, LIST Termsymblist) 
+/**********************************************************
+  INPUT:   A list indexes and a list of terms, i.e. a list of integers.
+  RETURNS: A LITPTR structure is created.
+  MEMORY:  The integers in the created structure are the integers
+           in indexList, no copies.
+***********************************************************/
+{
+  LITPTR lit_ptr;
+  LIST       Scan,varlist;
+  CLITERAL    literal;
+  int        index,n,k;
+
+  n                 = list_Length(Indexlist);
+
+  lit_ptr           = (LITPTR)memory_Malloc(sizeof(LITPTR_NODE));
+  litptr_SetLength(lit_ptr, n);
+  
+  if (n > 0) {
+    lit_ptr->litptr = (CLITERAL *)memory_Malloc(n * sizeof(CLITERAL));
+
+    k = 0;
+    for (Scan = Indexlist; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+      index         = (int)list_Car(Scan);
+      varlist       = (LIST)list_Car(Termsymblist);
+      Termsymblist  = list_Cdr(Termsymblist);
+      literal       = literal_Create(FALSE,index,varlist);
+
+      litptr_SetLiteral(lit_ptr, k, literal);
+            
+      k++;
+    }
+  } else 
+    lit_ptr->litptr = NULL;
+            
+  return lit_ptr;
+}
+
+
+void litptr_Delete(LITPTR lit_ptr) 
+/**********************************************************
+  INPUT:   A pointer to LITPTR.
+  MEMORY:  Deletes the LITPTR and frees the storage.
+***********************************************************/
+{
+  int        n,i;
+
+  n  = litptr_Length(lit_ptr);
+  
+  if (n > 0) {
+    for (i = 0; i < n; i++)
+      literal_Delete(litptr_Literal(lit_ptr,i));
+
+    memory_Free(lit_ptr->litptr, sizeof(CLITERAL) * n);
+    memory_Free(lit_ptr, sizeof(LITPTR_NODE));
+  } else
+    memory_Free(lit_ptr, sizeof(LITPTR_NODE));
+}
+
+
+void litptr_Print(LITPTR lit_ptr)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: void.
+  SUMMARY: Prints any term to stdout. 
+  CAUTION: Uses the other term_Output functions.
+***************************************************************/
+{ 
+  int i,n;
+
+  n = litptr_Length(lit_ptr);
+  /*n = lit_ptr->length;*/
+  
+  if (n > 0) {
+    printf("\nlength of LITPTR: %d\n",n);
+    for (i = 0; i < n; i++) {
+      printf("Entries of literal %d : \n",i);
+      puts("----------------------");
+      fputs("used:\t\t", stdout);
+
+      if (literal_GetUsed(litptr_Literal(lit_ptr,i)))
+      /*if (lit_ptr->litptr[i]->used)*/
+	puts("TRUE");
+      else 
+	puts("FALSE");
+      printf("litindex:\t%d\n",
+	     literal_GetLitIndex(litptr_Literal(lit_ptr,i)));
+      fputs("litvarlist:\t", stdout);
+      list_Apply((void (*)(POINTER)) symbol_Print,
+		 literal_GetLitVarList(litptr_Literal(lit_ptr,i)));
+      puts("\n");
+    }
+  }else 
+    puts("No entries in litptr structure");
+}
+
+
+BOOL litptr_AllUsed(LITPTR lit_ptr)
+/**************************************************************
+  INPUT:   A LITPTR.
+  RETURNS: TRUE if every literal in the LITPTR is used and 
+           FALSE otherwise.
+***************************************************************/
+{
+  int n,i;
+
+  n = litptr_Length(lit_ptr);
+
+  for (i = 0; i < n; i++)
+    if (!(literal_GetUsed(litptr_Literal(lit_ptr,i))))
+      return FALSE;
+
+  return TRUE;
+}
+
+
+LIST subs_CompList(LITPTR litptr)
+/**********************************************************
+  INPUT:   A pointer litptr.
+  RETURNS: A list with indexes which represents the first component of
+           with respect to the actual bindings and to litptr.
+  CAUTION: The structure to which litptr points to 
+           is changed destructively in the used slot.
+***********************************************************/
+{
+  BOOL found,hasinter;
+  LIST scan,complist,compindexlist;
+  int  n,i,j,lit;
+  
+  compindexlist     = list_Nil();   /* the result will be placed into this list */
+  complist          = list_Nil();   /* added afterwards */
+  n                 = litptr_Length(litptr);
+  
+  if (n > 0) {
+    for (j = 0; j < n; j++) {
+      printf("\nj = %d\n",j);
+      if (!literal_GetUsed(litptr_Literal(litptr,j))){
+	complist      = list_Nil();
+	complist      = list_Cons((POINTER)j,complist);
+	compindexlist = list_Cons((POINTER)(litptr->litptr[j]->litindex),
+				  compindexlist);
+	literal_PutUsed(litptr_Literal(litptr,j), TRUE);
+	j = n+1;
+	printf("\nj == %d\n",j);
+      }
+    }
+    
+    if (j == n){ 
+      list_Delete(complist);     /* There is no more component */
+      return compindexlist;      /* should be empty here       */
+    }
+    
+    found = TRUE;
+    while (found) {
+      found = FALSE;
+      for (scan = complist; !list_Empty(scan); scan = list_Cdr(scan)) {
+	lit = (int)list_Car(scan);
+	for (i = 0; i < n; i++) {
+	  if (!literal_GetUsed(litptr_Literal(litptr,i))) {
+	    printf("lit = %d\n",lit);
+	    printf("i   = %d\n",i);
+	    
+	    hasinter = list_HasIntersection(litptr->litptr[lit]->litvarlist,
+					    litptr->litptr[i]->litvarlist); 
+	    
+	    if (hasinter) {
+	      puts("hasinter = TRUE");
+	      complist      = list_Cons((POINTER)i,complist);
+	      compindexlist = list_Cons((POINTER)(litptr->litptr[i]->litindex),compindexlist); 
+	      literal_PutUsed(litptr_Literal(litptr,i), TRUE);
+	      found = TRUE;
+	    } 
+	  }      
+	}          
+      }
+      
+      if (!found) {      /* one component is finished */
+	list_Delete(complist);
+	found = FALSE;
+      }
+    }
+  }
+  
+  return compindexlist;
+}
diff --git a/test/spass/component.h b/test/spass/component.h
new file mode 100644
index 0000000000000000000000000000000000000000..14cb0962094258f95b32cf26d5fcc295d67f266b
--- /dev/null
+++ b/test/spass/component.h
@@ -0,0 +1,151 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *               COMPONENTS OF CLAUSES                    * */
+/* *                                                        * */
+/* *  $Module:   COMPONENT                                  * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 2000, 2001 MPI fuer Informatik    * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _COMPONENT_
+#define _COMPONENT_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "list.h"
+
+/**************************************************************/
+/* Structures                                                 */
+/**************************************************************/
+
+typedef struct cliteral {
+  BOOL  used;              /* Flag if the index is already used            */
+  int   litindex;          /* Index of the literal in the original clause  */ 
+  LIST  litvarlist;        /* List of variables of the literal             */
+} *CLITERAL, CLITERAL_NODE;
+
+
+typedef struct litptr {
+  CLITERAL *litptr;             /* Array of Pointer to literals           */
+  int     length;              /* Number of literal in the array *litptr */
+} *LITPTR, LITPTR_NODE;
+
+/**************************************************************/
+/* Macros                                                     */
+/**************************************************************/
+
+static __inline__ BOOL literal_GetUsed(CLITERAL C)
+{
+  return C->used;
+}
+
+static __inline__ int literal_GetLitIndex(CLITERAL C)
+{
+  return C->litindex;
+}
+
+static __inline__ LIST literal_GetLitVarList(CLITERAL C)
+{
+  return C->litvarlist;
+}
+
+static __inline__ void literal_PutUsed(CLITERAL C,BOOL Bool)
+{
+  C->used = Bool;
+}
+
+static __inline__ void literal_PutLitIndex(CLITERAL C, int I)
+{
+  C->litindex = I;
+}
+
+static __inline__ void literal_PutLitVarList(CLITERAL C, LIST L)
+{
+  C->litvarlist = L;
+}
+
+static __inline__ CLITERAL litptr_Literal(LITPTR C, int I)
+{
+  return C->litptr[I];
+}
+
+static __inline__ void litptr_SetLiteral(LITPTR LP, int I, CLITERAL CL)
+{
+  LP->litptr[I] = CL;
+}
+
+
+static __inline__ int litptr_Length(LITPTR C)
+{
+  return C->length;
+}
+
+static __inline__ void litptr_SetLength(LITPTR C, int n)
+{
+  C->length = n;
+}
+
+static __inline__ void litptr_IncLength(LITPTR C)
+{
+  (C->length)++;
+}
+
+static __inline__ void literal_Free(CLITERAL Lit)
+{
+  memory_Free(Lit, sizeof(CLITERAL_NODE));
+}
+
+
+/**************************************************************/
+/* Functions on a Component and on a Literal                  */
+/**************************************************************/
+
+CLITERAL literal_Create(BOOL, int, LIST);
+void     literal_Delete(CLITERAL);
+
+LITPTR   litptr_Create(LIST, LIST);
+void     litptr_Delete(LITPTR);
+void     litptr_Print(LITPTR);
+BOOL     litptr_AllUsed(LITPTR);
+
+
+#endif
diff --git a/test/spass/condensing.c b/test/spass/condensing.c
new file mode 100644
index 0000000000000000000000000000000000000000..fca04bf614091822182effa3f35662c9d42da7a4
--- /dev/null
+++ b/test/spass/condensing.c
@@ -0,0 +1,100 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *               CONDENSATION OF CLAUSES                  * */
+/* *                                                        * */
+/* *  $Module:   CONDENSING                                 * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 2001 MPI fuer Informatik    * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "subsumption.h"
+#include "misc.h"
+#include "condensing.h"
+
+
+LIST cond_CondFast(CLAUSE c)
+/**********************************************************
+  INPUT:   A clause c.
+  RETURNS: A list with indexes with respect to c that can
+           be deleted due to condensing.
+  CAUTION: None.
+***********************************************************/
+{
+  int    vec, i, j, k;
+  LIST   indexlist;
+
+  indexlist = list_Nil();
+  vec       = vec_ActMax();
+  
+  for (i = 0; i < clause_Length(c); i++) {
+    vec_Push((POINTER) i);
+  }
+  
+  for (k = clause_Length(c) - 1; k >= 0; k--) {
+    for (i = vec; i < vec_ActMax(); i++) {
+      if ((int)vec_GetNth(i) != k) {
+	cont_StartBinding();
+	if (unify_Match(cont_LeftContext(),
+			clause_GetLiteralTerm(c,k),
+			clause_GetLiteralTerm(c,(int)vec_GetNth(i)))) {
+	  cont_BackTrack();
+	  for (j = vec; j < vec_ActMax(); j++) {
+	    if (k == (int)vec_GetNth(j)) {
+	      vec_Swap((vec_ActMax() -1) ,j);
+	      j = vec_ActMax();
+	    }
+	  }
+	  
+	  if (subs_IdcRes(c,vec,(vec_ActMax() -1))) {
+	    indexlist = list_Cons((POINTER)k,indexlist);
+	    vec_Pop();
+	  }
+	  
+	  i = vec_ActMax()+1;
+	}
+	else
+	  cont_BackTrack();
+      }
+    }
+  }
+ 
+  vec_SetMax(vec);
+  return indexlist;
+}
diff --git a/test/spass/condensing.h b/test/spass/condensing.h
new file mode 100644
index 0000000000000000000000000000000000000000..7da40a50fe755ed24ed12b0c0f47d8a72d860605
--- /dev/null
+++ b/test/spass/condensing.h
@@ -0,0 +1,64 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *               CONDENSATION OF CLAUSES                  * */
+/* *                                                        * */
+/* *  $Module:   CONDENSING                                 * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 2001 MPI fuer Informatik          * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _CONDENSING_
+#define _CONDENSING_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "unify.h"
+
+
+/**************************************************************/
+/* Function Prototypes                                        */
+/**************************************************************/
+
+LIST cond_CondFast(CLAUSE);
+
+
+#endif
diff --git a/test/spass/context.c b/test/spass/context.c
new file mode 100644
index 0000000000000000000000000000000000000000..7d3aacbe714191dcf728fdfde53c796d53513728
--- /dev/null
+++ b/test/spass/context.c
@@ -0,0 +1,636 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                CONTEXTS FOR VARIABLES                  * */
+/* *                                                        * */
+/* *  $Module:   CONTEXT                                    * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1997, 1998, 1999, 2000, 2001            * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "context.h"
+
+/**************************************************************/
+/* Global Variables                                           */
+/**************************************************************/
+
+int     cont_NOOFCONTEXTS;
+LIST    cont_LISTOFCONTEXTS;
+int     cont_BINDINGS;
+
+SYMBOL  cont_INDEXVARSCANNER;
+
+CONTEXT cont_LASTBINDING;     /* The last binding made. */
+CONTEXT cont_CURRENTBINDING;  /* Help variable. */
+
+CONTEXT cont_LEFTCONTEXT;
+CONTEXT cont_RIGHTCONTEXT;
+CONTEXT cont_INSTANCECONTEXT;
+
+cont_STACK_TYPE cont_STACK;
+int             cont_STACKPOINTER;
+
+cont_CHECKSTACK_TYPE cont_CHECKSTACK;
+int                  cont_CHECKSTACKPOINTER;
+
+CONTEXT cont_STATELASTBINDING; /* Storage to save state of trails. */
+int     cont_STATEBINDINGS;    /* Storage to save number of current bindings. */
+int     cont_STATESTACK;       /* Storage to save state of stack. */
+int     cont_STATETOPSTACK;    /* Storage to save state of the top element of the stack. */
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *							    * */
+/* *  INITIALIZATION           			            * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+void cont_Init(void)
+/**********************************************************
+  INPUT:   None.
+  RETURNS: None.
+  EFFECT:  Initializes the unify module.
+********************************************************/
+{
+  cont_LASTBINDING     = (CONTEXT)NULL;
+
+  cont_ResetIndexVarScanner();
+
+  cont_NOOFCONTEXTS    = 0;
+  cont_LISTOFCONTEXTS  = list_Nil();
+  cont_BINDINGS        = 0;
+
+  cont_INSTANCECONTEXT = (CONTEXT)memory_Malloc(sizeof(CONTEXT_NODE));
+
+  cont_LEFTCONTEXT     = cont_Create();
+  cont_RIGHTCONTEXT    = cont_Create();
+
+  cont_StackInit();
+  cont_StackPush(0);
+  cont_StackPop();
+}
+
+
+void cont_Check(void)
+/**********************************************************
+  INPUT:   None.
+  RETURNS: None.
+  EFFECT:  Frees internal structures of the unify module.
+********************************************************/
+{
+#ifdef CHECK
+  if (cont_LASTBINDING || (cont_BINDINGS != 0) ||
+      !symbol_Equal(cont_INDEXVARSCANNER,
+		    symbol_GetInitialIndexVarCounter())) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cont_Check: There are variable bindings not reset.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+}
+
+
+void cont_Free(void)
+/**********************************************************
+  INPUT:   None.
+  RETURNS: None.
+  EFFECT:  Frees internal structures of the unify module.
+********************************************************/
+{
+  cont_Check();
+
+  while (cont_NOOFCONTEXTS > 0)
+    cont_Delete(list_Car(cont_LISTOFCONTEXTS)); /* Decreases NOOFCONTEXTS */
+
+  cont_BINDINGS = 0;
+
+  memory_Free(cont_INSTANCECONTEXT, sizeof(CONTEXT_NODE));
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *							    * */
+/* *  TERM EQUALITY WITH RESPECT TO BOUND VARIABLES         * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL cont_TermEqual(CONTEXT Context1, TERM Term1, CONTEXT Context2, TERM Term2)
+/*********************************************************
+  INPUT:   Two terms and two contexts.
+  RETURNS: TRUE iff the two terms are equal, where
+           variables are interpreted with respect to
+	   the bindings in the contexts.
+********************************************************/
+{
+#ifdef CHECK
+  if (!(term_IsTerm(Term1) && term_IsTerm(Term2))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cont_TermEqual: Input terms are corrupted.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Term1 = cont_Deref(&Context1,Term1);
+  Term2 = cont_Deref(&Context2,Term2);
+
+  if (!term_EqualTopSymbols(Term1, Term2))
+    return FALSE;
+  else if (term_ArgumentList(Term1)) {
+    LIST Scan1, Scan2;
+    for (Scan1=term_ArgumentList(Term1), Scan2=term_ArgumentList(Term2);
+	 list_Exist(Scan1) && list_Exist(Scan2);
+	 Scan1=list_Cdr(Scan1), Scan2=list_Cdr(Scan2))
+      if (!cont_TermEqual(Context1,list_Car(Scan1), Context2,list_Car(Scan2)))
+	return FALSE;
+    return (list_Empty(Scan1) ? list_Empty(Scan2) : FALSE);
+  } else
+    return TRUE;
+}
+
+
+BOOL cont_TermEqualModuloBindings(CONTEXT IndexContext, CONTEXT CtL, TERM TermL,
+				  CONTEXT CtR, TERM TermR)
+/*********************************************************
+  INPUT:   Two contexts, two terms.
+  RETURNS: The boolean value TRUE if the terms are equal.
+  CAUTION: EQUAL FUNCTION- OR PREDICATE SYMBOLS SHARE THE
+           SAME ARITY. THIS IS NOT VALID FOR JUNCTORS!
+*******************************************************/
+{   
+#ifdef CHECK
+  if (!(term_IsTerm(TermL) && term_IsTerm(TermR))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cont_TermEqualModuloBindings: Input terms are corrupted.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  while (term_IsVariable(TermL)) {
+    SYMBOL TermTop;
+
+    TermTop = term_TopSymbol(TermL);
+
+    if (symbol_IsIndexVariable(TermTop))
+      CtL = IndexContext;
+    else if (CtL == cont_InstanceContext())
+      break;
+
+    if (cont_VarIsBound(CtL, TermTop)) {
+      CONTEXT CHelp;
+
+      CHelp = cont_ContextBindingContext(CtL, TermTop);
+      TermL = cont_ContextBindingTerm(CtL, TermTop);
+      CtL   = CHelp;
+    } else
+      break;
+  }
+
+  while (term_IsVariable(TermR)) {
+    SYMBOL TermTop;
+
+    TermTop = term_TopSymbol(TermR);
+
+    if (symbol_IsIndexVariable(TermTop))
+      CtR = IndexContext;
+    else if (CtR == cont_InstanceContext())
+      break;
+
+    if (cont_VarIsBound(CtR, TermTop)) {
+      CONTEXT CHelp;
+
+      CHelp = cont_ContextBindingContext(CtR, TermTop);
+      TermR = cont_ContextBindingTerm(CtR, TermTop);
+      CtR   = CHelp;
+    } else
+      break;
+  }
+
+  if (!term_EqualTopSymbols(TermL, TermR))
+    return FALSE;
+  else 
+    if (term_IsVariable(TermL)) {
+      if (CtL == CtR)
+	return TRUE;
+      else
+	return FALSE;
+    }
+    else 
+      if (term_IsComplex(TermL)) {
+	LIST ScanL, ScanR;
+	
+	for (ScanL=term_ArgumentList(TermL), ScanR=term_ArgumentList(TermR);
+	     list_Exist(ScanL) && list_Exist(ScanR);
+	     ScanL=list_Cdr(ScanL), ScanR=list_Cdr(ScanR))
+	  if (!cont_TermEqualModuloBindings(IndexContext, CtL, list_Car(ScanL),
+					    CtR, list_Car(ScanR)))
+	    return FALSE;
+	
+	return (list_Empty(ScanL) ? list_Empty(ScanR) : FALSE);
+	
+      } 
+      else
+	return TRUE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *							    * */
+/* *  APPLY BINDINGS                                        * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+TERM cont_CopyAndApplyBindings(CONTEXT TermContext, TERM Term)
+{
+  while (term_IsVariable(Term)) {
+    SYMBOL TermTop;
+
+    TermTop = term_TopSymbol(Term);
+
+    if (cont_VarIsBound(TermContext, TermTop)) {
+      CONTEXT HelpContext;
+
+      HelpContext = cont_ContextBindingContext(TermContext, TermTop);
+      Term        = cont_ContextBindingTerm(TermContext, TermTop);
+      TermContext = HelpContext;
+    } else
+      break;
+  }
+
+  if (term_IsComplex(Term)) {
+    LIST Scan, ArgumentList;
+    for (Scan = ArgumentList = list_Copy(term_ArgumentList(Term));
+	 !list_Empty(Scan);
+	 Scan = list_Cdr(Scan))
+      list_Rplaca(Scan, cont_CopyAndApplyBindings(TermContext, list_Car(Scan)));
+    return term_Create(term_TopSymbol(Term), ArgumentList);
+  } else 
+    return term_Create(term_TopSymbol(Term), list_Nil());
+}
+
+
+TERM cont_CopyAndApplyBindingsCom(const CONTEXT Context, TERM Term)
+{
+  while (term_IsVariable(Term) && cont_VarIsBound(Context, term_TopSymbol(Term)))
+    Term = cont_ContextBindingTerm(Context, term_TopSymbol(Term));
+
+  if (term_IsComplex(Term)) {
+    LIST Scan, ArgumentList;
+    for (Scan = ArgumentList = list_Copy(term_ArgumentList(Term));
+	 !list_Empty(Scan);
+	 Scan = list_Cdr(Scan))
+      list_Rplaca(Scan, cont_CopyAndApplyBindingsCom(Context, list_Car(Scan)));
+    return term_Create(term_TopSymbol(Term), ArgumentList);
+  } else 
+    return term_Create(term_TopSymbol(Term), list_Nil());
+}
+
+
+TERM cont_ApplyBindingsModuloMatching(const CONTEXT Context, TERM Term,
+				      BOOL VarCheck)
+/**********************************************************
+  INPUT:   A context, a term, and a boolean flag.
+  RETURNS: <Term> is destructively changed with respect to
+           established bindings in the context.
+	   If <VarCheck> is true, all variables in <Term>
+	   must be bound in the context. When compiled with
+	   "CHECK" on, this condition is in fact checked.
+	   This function only makes sense after a matching operation.
+***********************************************************/
+{
+  TERM   RplacTerm;
+  LIST   Arglist;
+  SYMBOL Top;
+
+#ifdef CHECK
+  if (VarCheck && symbol_IsVariable(term_TopSymbol(Term)) &&
+      !cont_VarIsBound(Context, term_TopSymbol(Term))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cont_ApplyBindingsModuloMatching:");
+    misc_ErrorReport(" Used in forbidden context.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Top = term_TopSymbol(Term);
+
+  if (symbol_IsVariable(Top)) {
+    
+    if (cont_VarIsBound(Context, Top)) {
+      RplacTerm = cont_ContextBindingTerm(Context, Top);
+      Arglist   = term_CopyTermList(term_ArgumentList(RplacTerm));
+      term_RplacTop(Term, term_TopSymbol(RplacTerm));
+      term_DeleteTermList(term_ArgumentList(Term));
+      term_RplacArgumentList(Term, Arglist); 
+    }
+  }
+  else {
+    
+    for (Arglist = term_ArgumentList(Term);
+	 !list_Empty(Arglist);
+	 Arglist = list_Cdr(Arglist))
+      cont_ApplyBindingsModuloMatching(Context, list_Car(Arglist), VarCheck);
+  }     
+
+  return Term;
+}
+
+
+static TERM cont_CopyAndApplyIndexVariableBindings(const CONTEXT Context, TERM Term)
+{
+  SYMBOL TermTop;
+
+#ifdef CHECK
+  if (symbol_IsIndexVariable(term_TopSymbol(Term)) &&
+      !cont_VarIsBound(Context, term_TopSymbol(Term))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cont_CopyAndApplyIndexVariableBindings:");
+    misc_ErrorReport(" Expected bound index variable.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  TermTop = term_TopSymbol(Term);
+
+  while (symbol_IsIndexVariable(TermTop)) {
+    if (cont_VarIsBound(Context, TermTop)) {
+      Term    = cont_ContextBindingTerm(Context, TermTop);
+      TermTop = term_TopSymbol(Term);
+    }
+  }
+
+  if (term_IsComplex(Term)) {
+    LIST Scan, ArgumentList;
+    for (Scan = ArgumentList = list_Copy(term_ArgumentList(Term));
+	 !list_Empty(Scan);
+	 Scan = list_Cdr(Scan))
+      list_Rplaca(Scan, cont_CopyAndApplyIndexVariableBindings(Context, list_Car(Scan)));
+    return term_Create(TermTop, ArgumentList);
+  } else 
+    return term_Create(TermTop, list_Nil());
+}
+
+
+TERM cont_ApplyBindingsModuloMatchingReverse(const CONTEXT Context, TERM Term)
+/**********************************************************
+  INPUT:   A term.
+  RETURNS: <Term> is destructively changed with respect to
+           established bindings in the leftmost context. This
+           function only make sense after a matching operation (reverse).
+***********************************************************/
+{
+  TERM   RplacTerm;
+  LIST   Arglist;
+  SYMBOL Top;
+
+#ifdef CHECK
+  if (symbol_IsVariable(term_TopSymbol(Term)) &&
+      !cont_VarIsBound(Context, term_TopSymbol(Term))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cont_ApplyBindingsModuloMatchingReverse:");
+    misc_ErrorReport(" Used in forbidden context.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+    
+  Top = term_TopSymbol(Term);
+
+  if (symbol_IsVariable(Top)) {
+    
+    if (cont_VarIsBound(Context, Top)) {
+      RplacTerm =
+	cont_CopyAndApplyIndexVariableBindings(Context,
+						  cont_ContextBindingTerm(Context, Top));
+      term_RplacTop(Term, term_TopSymbol(RplacTerm));
+      term_DeleteTermList(term_ArgumentList(Term));
+      term_RplacArgumentList(Term, term_ArgumentList(RplacTerm));
+      term_Free(RplacTerm);
+    }
+  }
+  else {
+    
+    for (Arglist = term_ArgumentList(Term); !list_Empty(Arglist);
+	 Arglist = list_Cdr(Arglist))
+      cont_ApplyBindingsModuloMatchingReverse(Context, list_Car(Arglist));
+  }     
+
+  return Term;
+}
+
+
+BOOL cont_BindingsAreRenamingModuloMatching(const CONTEXT RenamingContext)
+{
+  CONTEXT Context;
+
+#ifdef CHECK
+  if (!cont_IsContextEmpty(RenamingContext)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cont_BindingsAreRenamingModuloMatching:");
+    misc_ErrorReport(" Renaming context contains bindings.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  cont_StartBinding();
+
+  Context = cont_LastBinding();
+
+  while (Context) {
+    
+    if (!symbol_IsIndexVariable(cont_BindingSymbol(Context))) {
+      SYMBOL CodomainSymbol;
+
+      CodomainSymbol = term_TopSymbol(cont_BindingTerm(Context));
+
+      if (symbol_IsVariable(CodomainSymbol)) {
+	if (cont_VarIsRenamed(RenamingContext, CodomainSymbol)) {
+	  cont_BackTrack();
+	  return FALSE;
+	} else {
+	  cont_CreateBinding(RenamingContext, CodomainSymbol, NULL, NULL);
+	  cont_SetContextBindingRenaming(RenamingContext, CodomainSymbol, CodomainSymbol);
+	}
+      } else {
+	cont_BackTrack();
+	return FALSE;
+      }
+    }
+
+    Context = cont_BindingLink(Context);
+  }
+
+  cont_BackTrack();
+  return TRUE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *							    * */
+/* *  MISC FUNCTIONS                                        * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+SYMBOL cont_TermMaxVar(CONTEXT Context, TERM Term)
+/*********************************************************
+  INPUT:   A context and a term.
+  RETURNS: The maximal variable in <Term> with respect to
+           the bindings in <Context>
+********************************************************/
+{
+  LIST   scan;
+  SYMBOL result;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cont_TermMaxVar: Input term is corrupted.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Term   = cont_Deref(&Context,Term);
+  result = symbol_Null();
+
+  if (term_IsStandardVariable(Term)) {
+    if (term_TopSymbol(Term) > result)
+      result = term_TopSymbol(Term);
+  } else {
+    for (scan = term_ArgumentList(Term); !list_Empty(scan); scan = list_Cdr(scan)) {
+      SYMBOL max = cont_TermMaxVar(Context, list_Car(scan));
+      
+      if (max > result)
+	result = max;
+    }
+  }
+
+  return result;
+}
+
+
+NAT cont_TermSize(CONTEXT Context, TERM Term)
+/*********************************************************
+  INPUT:   A context and a term.
+  RETURNS: The number of symbols in <Term> with respect to
+           the bindings in <Context>
+********************************************************/
+{
+  NAT  result;
+  LIST scan;
+
+  Term = cont_Deref(&Context, Term);
+  result = 1;
+  for (scan = term_ArgumentList(Term); !list_Empty(scan); scan = list_Cdr(scan))
+    result += cont_TermSize(Context, list_Car(scan));
+
+  return result;
+}
+
+
+BOOL cont_TermContainsSymbol(CONTEXT Context, TERM Term, SYMBOL Symbol)
+/*********************************************************
+  INPUT:   A context, a term and a symbol.
+  RETURNS: TRUE, if <Symbol> occurs in <Term> with respect to
+           the bindings in <Context>, FALSE otherwise.
+********************************************************/
+{
+  LIST scan;
+
+  Term = cont_Deref(&Context, Term);
+
+  if (symbol_Equal(term_TopSymbol(Term), Symbol))
+    return TRUE;
+  else
+    for (scan = term_ArgumentList(Term); !list_Empty(scan); scan = list_Cdr(scan)) {
+      if (cont_TermContainsSymbol(Context, list_Car(scan), Symbol))
+	return TRUE;
+    }
+
+  return FALSE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *							    * */
+/* *  OUTPUT             			            * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+void cont_TermPrintPrefix(CONTEXT Context, TERM Term)
+/**************************************************************
+  INPUT:   A context and a term.
+  RETURNS: none.
+  SUMMARY: Prints the term modulo the context to stdout. 
+  CAUTION: none.
+***************************************************************/
+{
+  Term = cont_Deref(&Context, Term);
+
+  symbol_Print(term_TopSymbol(Term));
+
+  if (term_IsComplex(Term)) {
+    LIST List;
+
+    putchar('(');
+
+    for (List = term_ArgumentList(Term); !list_Empty(List);
+	 List = list_Cdr(List)) {
+      cont_TermPrintPrefix(Context, list_Car(List));
+
+      if (!list_Empty(list_Cdr(List)))
+	putchar(',');
+    }
+
+    putchar(')');
+  }
+}
diff --git a/test/spass/context.h b/test/spass/context.h
new file mode 100644
index 0000000000000000000000000000000000000000..a3239ac825385ca9ad5241e620208585bf340d46
--- /dev/null
+++ b/test/spass/context.h
@@ -0,0 +1,1049 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                CONTEXTS FOR VARIABLES                  * */
+/* *                                                        * */
+/* *  $Module:   CONTEXT                                    * */
+/* *                                                        * */
+/* *  Copyright (C) 1997, 1998, 1999, 2000, 2001            * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#define SHOWBINDINGS 0
+
+#ifndef _CONTEXT_
+#define _CONTEXT_
+
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "term.h"
+#include "symbol.h"
+#include "list.h"
+
+/**************************************************************/
+/* Structures                                                 */
+/**************************************************************/
+
+/* Set 'SHOWBINDINGS' to non-zero value to enable debug output. */
+/* #define SHOWBINDINGS 1 */
+
+#define cont__SIZE symbol__MAXVARIABLES
+
+extern int  cont_NOOFCONTEXTS;
+extern LIST cont_LISTOFCONTEXTS;
+extern int  cont_BINDINGS;
+
+/* An array to remember bindings for the variables. The array     */
+/* is indexed by the variable index and holds the binding term.   */
+
+typedef struct binding {
+  SYMBOL         symbol;
+  SYMBOL         renaming;
+  TERM           term;
+  struct binding *context;
+  struct binding *link;
+} *CONTEXT, CONTEXT_NODE;
+
+extern CONTEXT cont_LASTBINDING;     /* The last binding made. */
+extern CONTEXT cont_CURRENTBINDING;  /* Help variable. */
+
+extern SYMBOL cont_INDEXVARSCANNER;
+
+/* Two contexts are allocated by default */
+
+extern CONTEXT cont_LEFTCONTEXT;
+extern CONTEXT cont_RIGHTCONTEXT;
+extern CONTEXT cont_INSTANCECONTEXT; /* This context is used as a label only (dummy context) */
+
+
+static __inline__ CONTEXT cont_LeftContext(void)
+{
+  return cont_LEFTCONTEXT;
+}
+
+static __inline__ CONTEXT cont_RightContext(void)
+{
+  return cont_RIGHTCONTEXT;
+}
+
+static __inline__ CONTEXT cont_InstanceContext(void)
+{
+  return cont_INSTANCECONTEXT;
+}
+
+/**************************************************************/
+/* A stack for the number of established bindings             */
+/**************************************************************/
+
+#define cont__STACKSIZE 1000
+
+typedef int cont_STACK_TYPE[cont__STACKSIZE];
+
+extern cont_STACK_TYPE cont_STACK;
+extern int             cont_STACKPOINTER;
+
+/* Stack operations */
+
+static __inline__ void cont_StackInit(void)
+{
+  cont_STACKPOINTER = 1;
+}
+
+static __inline__ void cont_StackPush(int Entry)
+{
+#ifdef CHECK
+  if (cont_STACKPOINTER >= cont__STACKSIZE) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cont_StackPush: Context stack overflow!\n");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  cont_STACK[cont_STACKPOINTER++] = Entry;
+}
+
+static __inline__ void cont_StackPop(void)
+{
+  --cont_STACKPOINTER;
+}
+
+static __inline__ int cont_StackPopResult(void)
+{
+  return cont_STACK[--cont_STACKPOINTER];
+}
+
+static __inline__ void cont_StackNPop(int N)
+{
+  cont_STACKPOINTER -= N;
+}
+
+static __inline__ int cont_StackTop(void)
+{
+  return cont_STACK[cont_STACKPOINTER - 1];
+}
+
+static __inline__ int cont_StackNthTop(int N)
+{
+  return cont_STACK[cont_STACKPOINTER - (1 + N)];
+}
+
+static __inline__ void cont_StackRplacTop(int Entry)
+{
+  cont_STACK[cont_STACKPOINTER - 1] = Entry;
+}
+
+static __inline__ void cont_StackRplacNthTop(int N, int Entry)
+{
+  cont_STACK[cont_STACKPOINTER - (1 + N)] = Entry;
+}
+
+static __inline__ void cont_StackRplacNth(int N, int Entry)
+{
+  cont_STACK[N] = Entry;
+}
+
+static __inline__ int cont_StackBottom(void)
+{
+  return cont_STACKPOINTER;
+}
+
+static __inline__ void cont_StackSetBottom(int Pointer)
+{
+  cont_STACKPOINTER = Pointer;
+}
+
+static __inline__ BOOL cont_StackEmpty(int Pointer)
+{
+  return cont_STACKPOINTER == Pointer;
+}
+
+
+static __inline__ void cont_StartBinding(void)
+{
+  cont_StackPush(cont_BINDINGS);
+
+  cont_BINDINGS = 0;
+}
+
+static __inline__ int cont_BindingsSinceLastStart(void)
+{
+  return cont_BINDINGS;
+}
+
+static __inline__ void cont_StopAndStartBinding(void)
+{
+  cont_StackRplacTop(cont_StackTop() + cont_BINDINGS);
+
+  cont_BINDINGS = 0;
+}
+
+/**************************************************************/
+/* Access                                                     */
+/**************************************************************/
+
+static __inline__ CONTEXT cont_Binding(CONTEXT C, SYMBOL Var)
+{
+  return &(C)[Var];
+}
+
+static __inline__ CONTEXT cont_BindingLink(CONTEXT B)
+{
+  return B->link;
+}
+
+static __inline__ void cont_SetBindingLink(CONTEXT B, CONTEXT L)
+{
+  B->link = L;
+}
+
+static __inline__ TERM cont_BindingTerm(CONTEXT B)
+{
+  return B->term;
+}
+
+static __inline__ void cont_SetBindingTerm(CONTEXT B, TERM T)
+{
+  B->term = T;
+}
+
+static __inline__ SYMBOL cont_BindingSymbol(CONTEXT B)
+{
+  return B->symbol;
+}
+
+static __inline__ void cont_SetBindingSymbol(CONTEXT B, SYMBOL S)
+{
+  B->symbol = S;
+}
+
+static __inline__ SYMBOL cont_BindingRenaming(CONTEXT B)
+{
+  return B->renaming;
+}
+
+static __inline__ void cont_SetBindingRenaming(CONTEXT B, SYMBOL S)
+{
+  B->renaming = S;
+}
+
+static __inline__ CONTEXT cont_BindingContext(CONTEXT B)
+{
+  return B->context;
+}
+
+static __inline__ void cont_SetBindingContext(CONTEXT B, CONTEXT C)
+{
+  B->context = C;
+}
+
+static __inline__ CONTEXT cont_ContextBindingLink(CONTEXT C,SYMBOL Var)
+{
+  return C[Var].link;
+}
+
+static __inline__ TERM cont_ContextBindingTerm(CONTEXT C,SYMBOL Var)
+{
+  return C[Var].term;
+}
+
+static __inline__ void cont_SetContextBindingTerm(CONTEXT C, SYMBOL Var, TERM t)
+{
+  C[Var].term = t;
+}
+
+static __inline__ SYMBOL cont_ContextBindingSymbol(CONTEXT C,SYMBOL Var)
+{
+  return C[Var].symbol;
+}
+
+static __inline__ SYMBOL cont_ContextBindingRenaming(CONTEXT C,SYMBOL Var)
+{
+  return C[Var].renaming;
+}
+
+static __inline__ void cont_SetContextBindingRenaming(CONTEXT C, SYMBOL Var,
+						       SYMBOL R)
+{
+  C[Var].renaming = R;
+}
+
+static __inline__ CONTEXT cont_ContextBindingContext(CONTEXT C,SYMBOL Var)
+{
+  return C[Var].context;
+}
+
+/**************************************************************/
+/* Predicates                                                 */
+/**************************************************************/
+
+static __inline__ BOOL cont_VarIsBound(CONTEXT C, SYMBOL Var)
+{
+  return cont_ContextBindingTerm(C,Var) != (TERM) NULL;
+}
+
+static __inline__ BOOL cont_VarIsUsed(CONTEXT C, SYMBOL Var)
+{
+  return cont_ContextBindingContext(C,Var) != (CONTEXT) NULL;
+}
+
+static __inline__ BOOL cont_VarIsLinked(CONTEXT C, SYMBOL Var)
+{
+  return cont_ContextBindingLink(C,Var) != (CONTEXT) NULL;
+}
+
+static __inline__ BOOL cont_VarIsRenamed(CONTEXT C, SYMBOL Var)
+{
+  return cont_ContextBindingRenaming(C, Var) != symbol_Null();
+}
+
+static __inline__ BOOL cont_VarIsClosed(CONTEXT C,SYMBOL Var)
+{
+  return !cont_VarIsBound(C,Var) && cont_VarIsUsed(C,Var);
+}
+
+static __inline__ BOOL cont_BindingIsBound(CONTEXT B)
+{
+  return cont_BindingTerm(B) != (TERM) NULL;
+}
+
+static __inline__ BOOL cont_BindingIsUsed(CONTEXT B)
+{
+  return cont_BindingContext(B) != (CONTEXT) NULL;
+}
+
+/**************************************************************/
+/* Aux functions for backtracking                             */
+/**************************************************************/
+
+static __inline__ CONTEXT cont_LastBinding(void)
+{
+  return cont_LASTBINDING;
+}
+
+static __inline__ void cont_SetLastBinding(CONTEXT B)
+{
+  cont_LASTBINDING = B;
+}
+
+static __inline__ TERM cont_LastBindingTerm(void)
+{
+  return cont_BindingTerm(cont_LastBinding());
+}
+
+static __inline__ SYMBOL cont_LastBindingSymbol(void)
+{
+  return cont_BindingSymbol(cont_LastBinding());
+}
+
+static __inline__ CONTEXT cont_LastBindingContext(void)
+{
+  return cont_BindingContext(cont_LastBinding());
+}
+
+static __inline__ BOOL cont_LastIsBound(void)
+{
+  return cont_BindingIsBound(cont_LastBinding());
+}
+
+static __inline__ BOOL cont_LastIsUsed(void)
+{
+  return cont_LastBindingContext() != (CONTEXT) NULL;
+}
+
+static __inline__ BOOL cont_LastIsClosed(void)
+{
+  return !cont_LastIsBound() && cont_LastIsUsed();
+}
+
+static __inline__ BOOL cont_IsInContext(CONTEXT C, SYMBOL Var, CONTEXT B)
+{
+  return cont_Binding(C, Var) == B;
+}
+
+static __inline__ CONTEXT cont_ContextOfBinding(CONTEXT B)
+{
+  CONTEXT Result;
+  LIST    Scan;
+
+  for (Result = NULL, Scan = cont_LISTOFCONTEXTS;
+       list_Exist(Scan);
+       Scan = list_Cdr(Scan)) {
+    if (cont_IsInContext(list_Car(Scan), cont_BindingSymbol(B), B)) {
+      Result = list_Car(Scan);
+      break;
+    }
+  }
+
+#ifdef CHECK
+  if (Result == NULL) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cont_ContextOfBinding: Unknown context.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  return Result;
+}
+
+/**************************************************************/
+/* Initialization                                             */
+/**************************************************************/
+
+static __inline__ void cont_InitBinding(CONTEXT C, SYMBOL Var)
+{
+  cont_CURRENTBINDING = cont_Binding(C, Var);
+  cont_SetBindingLink(cont_CURRENTBINDING, (CONTEXT)NULL);
+  cont_SetBindingTerm(cont_CURRENTBINDING, (TERM)NULL);
+  cont_SetBindingSymbol(cont_CURRENTBINDING, Var);
+  cont_SetBindingRenaming(cont_CURRENTBINDING, symbol_Null());
+  cont_SetBindingContext(cont_CURRENTBINDING, (CONTEXT)NULL);
+}
+
+static __inline__ void cont_InitContext(CONTEXT C)
+{
+  int i;
+
+  for (i = 0; i < cont__SIZE; i++)
+    cont_InitBinding(C, i);
+}
+
+/**************************************************************/
+/* Creation and deletion of contexts                          */
+/**************************************************************/
+
+static __inline__ CONTEXT cont_Create(void)
+{
+  CONTEXT Result;
+
+  Result = (CONTEXT)memory_Malloc(cont__SIZE*sizeof(CONTEXT_NODE));
+
+  cont_InitContext(Result);
+
+  cont_LISTOFCONTEXTS = list_Cons(Result, cont_LISTOFCONTEXTS);
+  cont_NOOFCONTEXTS++;
+
+  return Result;
+}
+    
+static __inline__ void cont_Delete(CONTEXT C)
+{
+#ifdef CHECK
+  if ((cont_NOOFCONTEXTS == 0) ||
+      !list_PointerMember(cont_LISTOFCONTEXTS, C)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cont_Delete: Context %ld not registered.\n",
+		     (unsigned long)C);
+    misc_FinishErrorReport();
+  }
+#endif
+
+  cont_LISTOFCONTEXTS = list_PointerDeleteOneElement(cont_LISTOFCONTEXTS, C);
+
+  cont_NOOFCONTEXTS--;
+
+  memory_Free(C, cont__SIZE*sizeof(CONTEXT_NODE));
+}
+
+static __inline__ void cont_ResetIndexVarScanner(void)
+{
+  cont_INDEXVARSCANNER = symbol_GetInitialIndexVarCounter();
+}
+
+/**************************************************************/
+/* Output bindings                                            */
+/**************************************************************/
+
+static __inline__ void cont_BindingOutput(CONTEXT C, SYMBOL Var)
+{
+  symbol_Print(cont_ContextBindingSymbol(C, Var));
+  putchar(':');
+  symbol_Print(Var);
+
+  fputs(" -> ", stdout);
+
+  if (cont_VarIsBound(C, Var)) {
+    term_PrintPrefix(cont_ContextBindingTerm(C, Var));
+  } else
+    fputs("unbound", stdout);
+
+  fputs(" in ", stdout);
+
+  if (cont_VarIsUsed(C, Var)) {
+    printf("%ld", (unsigned long)cont_ContextBindingContext(C, Var));
+  } else
+    fputs("NULL (unused)", stdout);
+
+  fputs(". ", stdout);
+
+  if (cont_VarIsClosed(C, Var)) {
+    fputs("(closed)", stdout);
+  }
+
+  if (!cont_VarIsBound(C, Var) &&
+      !cont_VarIsUsed(C, Var)) {
+    fputs(",(free)", stdout);
+  }
+
+  if (cont_VarIsRenamed(C, Var)) {
+    fputs(",(renamed): ", stdout);
+    symbol_Print(Var);
+    fputs(" -> ", stdout);
+    symbol_Print(cont_ContextBindingRenaming(C, Var));
+  } 
+  
+  fflush(stdout);
+}
+
+static __inline__ void cont_PrintCurrentTrail(void)
+{
+  fputs("\nPrint bindings:", stdout);
+  cont_CURRENTBINDING = cont_LastBinding();
+  while (cont_CURRENTBINDING) {
+    cont_BindingOutput(cont_ContextOfBinding(cont_CURRENTBINDING),
+		       cont_BindingSymbol(cont_CURRENTBINDING));
+    cont_CURRENTBINDING = cont_BindingLink(cont_CURRENTBINDING);
+    if (cont_CURRENTBINDING)
+      putchar('\n');
+  }
+  fflush(stdout);
+}
+
+/**************************************************************/
+/* Close bindings                                             */
+/**************************************************************/
+
+static __inline__ void cont_CloseBindingHelp(CONTEXT C, SYMBOL Var)
+{
+  cont_SetContextBindingTerm(C, Var, NULL);
+}
+
+static __inline__ void cont_CloseBindingBindingHelp(CONTEXT B)
+{
+  cont_SetBindingTerm(B, NULL);
+}
+
+#if SHOWBINDINGS
+static __inline__ void cont_CloseBinding(CONTEXT C, SYMBOL Var)
+{
+  fputs("\nClose binding from ", stdout);
+  cont_BindingOutput(C, Var);
+  cont_CloseBindingHelp(C, Var);
+}
+#else
+static __inline__ void cont_CloseBinding(CONTEXT C, SYMBOL Var)
+{
+  cont_CloseBindingHelp(C, Var);
+}
+#endif
+
+static __inline__ void cont_CloseBindingBinding(CONTEXT B) {
+  cont_CloseBindingBindingHelp(B);
+}
+
+/**************************************************************/
+/* Establish bindings                                         */
+/**************************************************************/
+
+static __inline__ void cont_CreateBindingHelp(CONTEXT C, SYMBOL Var,
+					      CONTEXT CTerm, TERM Term)
+{
+#ifdef CHECK
+  if (cont_VarIsBound(C, Var)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cont_CreateBindingHelp: Variable already bound.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  cont_CURRENTBINDING = cont_Binding(C,Var);
+  cont_SetBindingTerm(cont_CURRENTBINDING, Term);
+  cont_SetBindingContext(cont_CURRENTBINDING, CTerm);
+  cont_SetBindingLink(cont_CURRENTBINDING, cont_LastBinding());
+  cont_SetLastBinding(cont_CURRENTBINDING);
+}
+
+#if SHOWBINDINGS
+
+static __inline__ int cont_CreateBinding(CONTEXT C, SYMBOL Var, CONTEXT CTerm, TERM Term)
+{
+  cont_CreateBindingHelp(C,Var,CTerm,Term);
+  fputs("\nEstablish binding from ", stdout);
+  cont_BindingOutput(C, Var);
+  return ++cont_BINDINGS;
+}
+
+static __inline__ int cont_CreateClosedBinding(CONTEXT C, SYMBOL Var)
+{
+  cont_CreateBindingHelp(C, Var, C, NULL);
+  fputs("\nEstablish closed binding from ", stdout);
+  cont_BindingOutput(C,Var);
+  return ++cont_BINDINGS;
+}
+
+#else
+
+static __inline__ int cont_CreateBinding(CONTEXT C, SYMBOL Var, CONTEXT CTerm, TERM Term)
+{
+  cont_CreateBindingHelp(C,Var,CTerm,Term);
+  return ++cont_BINDINGS;
+}
+
+static __inline__ int cont_CreateClosedBinding(CONTEXT C, SYMBOL Var)
+{
+  cont_CreateBindingHelp(C, Var, C, NULL);
+  return ++cont_BINDINGS;
+}
+
+#endif
+
+/**************************************************************/
+/* Backtracking                                               */
+/**************************************************************/
+
+static __inline__ void cont_BackTrackLastBindingHelp(void)
+{
+  cont_CURRENTBINDING = cont_LastBinding();
+  cont_SetLastBinding(cont_BindingLink(cont_CURRENTBINDING));
+  cont_SetBindingTerm(cont_CURRENTBINDING, NULL);
+  cont_SetBindingContext(cont_CURRENTBINDING, NULL);
+  cont_SetBindingRenaming(cont_CURRENTBINDING, symbol_Null());
+  cont_SetBindingLink(cont_CURRENTBINDING, NULL);
+
+  cont_BINDINGS--;
+}
+
+#if SHOWBINDINGS
+
+static __inline__ void cont_BackTrackLastBinding(void)
+{
+  CONTEXT LastContext;
+  SYMBOL  LastSymbol;
+
+  LastContext = cont_ContextOfBinding(cont_LastBinding());
+  LastSymbol  = cont_LastBindingSymbol();
+  fputs("\nBacktrack binding from ", stdout);
+  cont_BindingOutput(LastContext, LastSymbol);
+  cont_BackTrackLastBindingHelp();
+}
+
+static __inline__ int cont_BackTrack(void)
+{
+  printf("\nBacktrack %d bindings:", cont_BINDINGS);
+
+  while (cont_BINDINGS > 0)
+    cont_BackTrackLastBinding();
+
+  if (!cont_StackEmpty(0))
+    cont_BINDINGS = cont_StackPopResult();
+
+  fflush(stdout);
+  return 0;
+}
+
+static __inline__ int cont_StopAndBackTrack(void)
+{
+#ifdef CHECK
+  if (cont_BINDINGS > 0) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cont_StopAndBackTrack: Bindings not reset!\n");
+    misc_FinishErrorReport();
+  } else if (cont_StackEmpty(0)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cont_StopAndBackTrack: No bindings on stack!\n");
+    misc_FinishErrorReport();
+  }
+#endif
+  cont_BINDINGS = cont_StackPopResult();
+
+  printf("\nStop and Backtrack %d bindings:", cont_BINDINGS);
+
+  while (cont_BINDINGS > 0)
+    cont_BackTrackLastBinding();
+
+  fflush(stdout);
+  return 0;
+}
+
+static __inline__ int cont_BackTrackAndStart(void)
+{
+  printf("\nBacktrack %d bindings:", cont_BINDINGS);
+
+  while (cont_BINDINGS > 0)
+    cont_BackTrackLastBinding();
+
+  fflush(stdout);
+  return 0;
+}
+
+static __inline__ void cont_Reset(void)
+{
+  fputs("\nReset bindings:", stdout);
+  while (cont_LastBinding())
+    cont_BackTrackLastBinding();
+
+  cont_BINDINGS = 0;
+  cont_StackInit();
+  cont_ResetIndexVarScanner();
+  fflush(stdout);
+}
+
+#else
+
+static __inline__ void cont_BackTrackLastBinding(void)
+{
+  cont_BackTrackLastBindingHelp();
+}
+
+static __inline__ int cont_BackTrack(void)
+{
+  while (cont_BINDINGS > 0)
+    cont_BackTrackLastBinding();
+
+  if (!cont_StackEmpty(0))
+    cont_BINDINGS = cont_StackPopResult();
+
+  return 0;
+}
+
+static __inline__ int cont_StopAndBackTrack(void)
+{
+#ifdef CHECK
+  if (cont_BINDINGS > 0) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cont_StopAndBackTrack: Bindings not reset!\n");
+    misc_FinishErrorReport();
+  } else if (cont_StackEmpty(0)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cont_StopAndBackTrack: No bindings on stack!\n");
+    misc_FinishErrorReport();
+  }
+#endif
+  cont_BINDINGS = cont_StackPopResult();
+
+  while (cont_BINDINGS > 0)
+    cont_BackTrackLastBinding();
+
+  return 0;
+}
+
+static __inline__ int cont_BackTrackAndStart(void)
+{
+  while (cont_BINDINGS > 0)
+    cont_BackTrackLastBinding();
+
+  return 0;
+}
+
+static __inline__ void cont_Reset(void)
+{
+  while (cont_LastBinding())
+    cont_BackTrackLastBinding();
+
+  cont_BINDINGS = 0;
+  cont_StackInit();
+  cont_ResetIndexVarScanner();
+}
+
+#endif
+
+/**************************************************************/
+/* Check state of bindings                                    */
+/**************************************************************/
+
+#define cont__CHECKSTACKSIZE  1000
+#define cont__CHECKSTACKEMPTY 0
+
+typedef POINTER cont_CHECKSTACK_TYPE[cont__CHECKSTACKSIZE];
+
+extern cont_CHECKSTACK_TYPE cont_CHECKSTACK;
+extern int                  cont_CHECKSTACKPOINTER;
+
+/* Stack operations */
+
+static __inline__ void cont_CheckStackInit(void)
+{
+  cont_CHECKSTACKPOINTER = cont__CHECKSTACKEMPTY;
+}
+
+static __inline__ void cont_CheckStackPush(POINTER Entry)
+{
+#ifdef CHECK
+  if (cont_CHECKSTACKPOINTER >= cont__STACKSIZE) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cont_CheckStackPush: Context check stack overflow!\n");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  cont_CHECKSTACK[cont_CHECKSTACKPOINTER++] = Entry;
+}
+
+static __inline__ void cont_CheckStackPop(void)
+{
+  --cont_CHECKSTACKPOINTER;
+}
+
+static __inline__ POINTER cont_CheckStackPopResult(void)
+{
+  return cont_CHECKSTACK[--cont_CHECKSTACKPOINTER];
+}
+
+static __inline__ void cont_CheckStackNPop(int N)
+{
+  cont_CHECKSTACKPOINTER -= N;
+}
+
+static __inline__ POINTER cont_CheckStackTop(void)
+{
+  return cont_CHECKSTACK[cont_CHECKSTACKPOINTER - 1];
+}
+
+static __inline__ POINTER cont_CheckStackNthTop(int N)
+{
+  return cont_CHECKSTACK[cont_CHECKSTACKPOINTER - (1 + N)];
+}
+
+static __inline__ void cont_CheckStackRplacTop(POINTER Entry)
+{
+  cont_CHECKSTACK[cont_CHECKSTACKPOINTER - 1] = Entry;
+}
+
+static __inline__ void cont_CheckStackRplacNthTop(int N, POINTER Entry)
+{
+  cont_CHECKSTACK[cont_CHECKSTACKPOINTER - (1 + N)] = Entry;
+}
+
+static __inline__ void cont_CheckStackRplacNth(int N, POINTER Entry)
+{
+  cont_CHECKSTACK[N] = Entry;
+}
+
+static __inline__ int cont_CheckStackBottom(void)
+{
+  return cont_CHECKSTACKPOINTER;
+}
+
+static __inline__ void cont_CheckStackSetBottom(int Pointer)
+{
+  cont_CHECKSTACKPOINTER = Pointer;
+}
+
+static __inline__ BOOL cont_CheckStackEmpty(int Pointer)
+{
+  return cont_CHECKSTACKPOINTER == Pointer;
+}
+
+extern CONTEXT cont_STATELASTBINDING; /* Storage to save state of trails. */
+extern int     cont_STATEBINDINGS;    /* Storage to save number of current bindings. */
+extern int     cont_STATESTACK;       /* Storage to save state of stack. */
+extern int     cont_STATETOPSTACK;    /* Storage to save state of the top element of the stack. */
+
+static __inline__ BOOL cont_CheckLastBinding(CONTEXT Check, int Bindings)
+{
+  CONTEXT Scan;
+  BOOL    Result;
+
+  Scan = cont_LastBinding();
+
+  while (Bindings > 0) {
+    Scan = cont_BindingLink(Scan);
+    Bindings--;
+  }
+  if (Check == Scan)
+    Result = TRUE;
+  else
+    Result = FALSE;
+
+  return Result;
+}
+
+static __inline__ void cont_CheckState(void)
+{
+  if (cont_CheckStackEmpty(cont__CHECKSTACKEMPTY)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cont_CheckState: No states saved.\n");
+    misc_FinishErrorReport();
+  }
+
+  cont_STATETOPSTACK    = (int)cont_CheckStackPopResult();
+  cont_STATESTACK       = (int)cont_CheckStackPopResult();
+  cont_STATEBINDINGS    = (int)cont_CheckStackPopResult();
+  cont_STATELASTBINDING = (CONTEXT)cont_CheckStackPopResult();
+
+  if ((cont_STATELASTBINDING != cont_LastBinding()) ||
+      (cont_STATEBINDINGS != cont_BINDINGS) ||
+      (!cont_StackEmpty(cont_STATESTACK)) ||
+      (cont_STATETOPSTACK != cont_StackTop())) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In cont_CheckState: State of contexts does not match saved state.");
+    misc_ErrorReport("\nTrail: Saved state: %ld; current state: %ld.",
+		     (long)cont_STATELASTBINDING, (long)cont_LastBinding());
+    misc_ErrorReport("\nNumber of bindings: Saved state: %d; current state: %d.",
+		     cont_STATEBINDINGS, cont_BINDINGS);
+    misc_ErrorReport("\nBinding stack pointer: Saved state: %d; current state: %d.",
+		     cont_STATESTACK, cont_StackBottom());
+    misc_ErrorReport("\nNumber of bindings on top of stack: Saved state: %d; current state: %d.\n\n",
+		     cont_STATETOPSTACK, cont_StackTop());
+    misc_FinishErrorReport();
+  }
+}
+
+static __inline__ void cont_SaveState(void)
+{
+  cont_CheckStackPush((POINTER)cont_LastBinding());
+  cont_CheckStackPush((POINTER)cont_BINDINGS);
+  cont_CheckStackPush((POINTER)cont_StackBottom());
+  cont_CheckStackPush((POINTER)cont_StackTop());
+}
+
+static __inline__ BOOL cont_IsContextEmpty(const CONTEXT Check)
+{
+  int i;
+
+  for (i = 0; i < cont__SIZE; i++)
+    if (cont_VarIsBound(Check, i) ||
+	cont_VarIsUsed(Check, i) ||
+	cont_VarIsLinked(Check, i) ||
+	cont_VarIsRenamed(Check, i))
+      return FALSE;
+
+  return TRUE;
+}
+
+/**************************************************************/
+/* Generation of index variables                              */
+/**************************************************************/
+
+static __inline__ SYMBOL cont_NextIndexVariable(const CONTEXT IndexContext)
+{
+  if (symbol_Equal(cont_INDEXVARSCANNER, symbol_LastIndexVariable()))
+    cont_INDEXVARSCANNER = symbol_CreateIndexVariable();
+  else
+    for (;;) {
+      cont_INDEXVARSCANNER = symbol_NextIndexVariable(cont_INDEXVARSCANNER);
+      if (!cont_VarIsUsed(IndexContext, cont_INDEXVARSCANNER)) 
+	break;
+      else 
+	if (symbol_Equal(cont_INDEXVARSCANNER, symbol_LastIndexVariable())) {
+	  cont_INDEXVARSCANNER = symbol_CreateIndexVariable();
+	  break;
+	}
+    }
+  return cont_INDEXVARSCANNER;
+}
+
+/**************************************************************/
+/* Dereferencing of terms wrt. contexts                       */
+/**************************************************************/
+
+static __inline__ TERM cont_Deref(CONTEXT* Context, TERM Term)
+/**************************************************************
+  INPUT:   A call-by-ref context and a term.
+  RETURNS: The dereferenced term and the corresponding context.
+  SUMMARY: Dereferences bindings of variables.
+  CAUTION: In general, the context of the returned term
+           is different to the input context.
+***************************************************************/
+{
+
+  while (term_IsVariable(Term) && *Context != cont_InstanceContext()) {
+    SYMBOL TermTop;
+
+    TermTop = term_TopSymbol(Term);
+
+    if (cont_VarIsBound(*Context, TermTop)) {
+      CONTEXT HelpContext;
+
+      HelpContext = cont_ContextBindingContext(*Context, TermTop);
+      Term        = cont_ContextBindingTerm(*Context, TermTop);
+      *Context    = HelpContext;
+    } 
+    else
+      return Term;
+  }
+
+  return Term;
+}
+
+/**************************************************************/
+/* Functions for Initialization and Controlling               */
+/**************************************************************/
+           
+void cont_Init(void);
+void cont_Check(void);
+void cont_Free(void);
+
+/**************************************************************/
+/* Functions for Term Equality Test with respect to Bindings  */
+/**************************************************************/
+
+BOOL cont_TermEqual(CONTEXT, TERM, CONTEXT, TERM);
+BOOL cont_TermEqualModuloBindings(CONTEXT, CONTEXT, TERM, CONTEXT, TERM);
+
+/**************************************************************/
+/* Functions for Applying Bindings                            */
+/**************************************************************/
+
+TERM   cont_CopyAndApplyBindings(CONTEXT, TERM);
+TERM   cont_CopyAndApplyBindingsCom(const CONTEXT, TERM);
+
+TERM   cont_ApplyBindingsModuloMatching(const CONTEXT, TERM, BOOL);
+TERM   cont_ApplyBindingsModuloMatchingReverse(const CONTEXT, TERM);
+
+BOOL   cont_BindingsAreRenamingModuloMatching(const CONTEXT);
+
+/**************************************************************/
+/* Misc Functions                                             */
+/**************************************************************/
+
+SYMBOL cont_TermMaxVar(CONTEXT, TERM);
+NAT    cont_TermSize(CONTEXT, TERM);
+BOOL   cont_TermContainsSymbol(CONTEXT, TERM, SYMBOL);
+
+/**************************************************************/
+/* Functions for Output                                       */
+/**************************************************************/
+
+void cont_TermPrintPrefix(CONTEXT, TERM);
+
+#endif
diff --git a/test/spass/defs.c b/test/spass/defs.c
new file mode 100644
index 0000000000000000000000000000000000000000..0b6268b9398a8519ad6e9e4d9bd1c9955efe7871
--- /dev/null
+++ b/test/spass/defs.c
@@ -0,0 +1,1359 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                       DEFINITIONS                      * */
+/* *                                                        * */
+/* *  $Module:   DEFS                                       * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1998, 1999, 2000, 2001                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "cnf.h"
+#include "defs.h"
+#include "foldfg.h"
+
+static void def_DeleteFromClauses(DEF);
+static void def_DeleteFromTerm(DEF);
+
+DEF def_CreateFromClauses(TERM ExpTerm, TERM PredTerm, LIST Clauses, LIST Lits,
+			  BOOL Con)
+/**********************************************************
+  INPUT:   Two terms, a list of clausenumbers, a list of literal indices and
+           a boolean saying whether all clauses derived by expanding the 
+	   predicate should be conclauses.
+  RETURNS: A definition consisting of the 2 terms as expansion term and
+           predicate term and the list of parent clause numbers and a list
+	   of the indices of the defined predicate in the parent clauses.
+	   ToProve and label are set to NULL.
+********************************************************/
+{
+  DEF  result;
+
+#ifdef CHECK
+  if (!term_IsTerm(ExpTerm) || !term_IsTerm(PredTerm)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In def_CreateFromClause: Illegal input.");
+    misc_FinishErrorReport();
+  }
+  if (list_Empty(Clauses)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In def_CreateFromClause: No parent clause given.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  result                   = (DEF) memory_Malloc(sizeof(DEF_NODE));
+  result->expansion        = ExpTerm;
+  result->predicate        = PredTerm;
+  result->toprove          = (TERM) NULL;
+  result->parentclauses    = list_PairCreate(Clauses, Lits);
+  result->label            = (const char*) NULL;
+  result->conjecture       = Con;
+
+  return result;
+}
+
+DEF def_CreateFromTerm(TERM ExpTerm, TERM PredTerm, TERM ToProve, const char* Label)
+/**********************************************************
+  INPUT:   3 terms and a term label.
+  RETURNS: A definition consisting of the 3 terms as expansion term,
+           predicate term and term to prove before applying the 
+	   definition and the label of the parent term.
+	   The list of clausenumbers is set to NULL.
+********************************************************/
+{
+  DEF  result;
+
+#ifdef CHECK
+  if (!term_IsTerm(ExpTerm) || !term_IsTerm(PredTerm)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In def_CreateFromTerm: Illegal input.");
+    misc_FinishErrorReport();
+  }  
+  if (Label ==  NULL) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In def_CreateFromTerm: No parent clause given.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  result                   = (DEF) memory_Malloc(sizeof(DEF_NODE));
+  result->expansion        = ExpTerm;
+  result->predicate        = PredTerm;
+  result->toprove          = ToProve;
+  result->parentclauses    = list_PairCreate(list_Nil(), list_Nil());
+  result->label            = Label;
+  result->conjecture       = FALSE;
+
+  return result;
+}
+
+static void def_DeleteFromClauses(DEF D) 
+/**********************************************************
+  INPUT:   A definition derived from clauses.
+  EFFECT:  The definition is deleted, INCLUDING THE TERMS AND
+           THE LIST OF CLAUSE NUMBERS.
+********************************************************/  
+{
+#ifdef CHECK
+  if (!term_IsTerm(def_Expansion(D)) || !term_IsTerm(def_Predicate(D))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In def_DeleteFormClauses: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  /* ToProve and Label are NULL */
+  term_Delete(def_Expansion(D));
+  term_Delete(def_Predicate(D));
+  list_Delete(def_ClauseNumberList(D));
+  list_Delete(def_ClauseLitsList(D));
+  list_PairFree(D->parentclauses);
+
+  memory_Free(D, sizeof(DEF_NODE));
+}
+
+static void def_DeleteFromTerm(DEF D) 
+/**********************************************************
+  INPUT:   A definition derived from a term.
+  EFFECT:  The definition is deleted, INCLUDING THE TERMS.
+           THE LABEL IS NOT FREED.
+********************************************************/  
+{
+#ifdef CHECK
+  if (!term_IsTerm(def_Expansion(D)) || !term_IsTerm(def_Predicate(D))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In def_DeleteFromTerm: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  /* List of clausenumbers is NULL */
+  term_Delete(def_Expansion(D));
+  term_Delete(def_Predicate(D));
+  if (def_ToProve(D) != (TERM) NULL)
+    term_Delete(def_ToProve(D));
+  list_PairFree(D->parentclauses);
+  memory_Free(D, sizeof(DEF_NODE));
+}
+
+void def_Delete(DEF D)
+/**********************************************************
+  INPUT:   A definition derived from a term.
+  EFFECT:  The definition is deleted.
+  CAUTION: All elements of the definition except of the label are freed.
+********************************************************/  
+{
+  if (!list_Empty(def_ClauseNumberList(D)))
+    def_DeleteFromClauses(D);
+  else
+    def_DeleteFromTerm(D);
+}
+
+int def_PredicateOccurrences(TERM Term, SYMBOL P)
+/****************************************************
+  INPUT:   A term and a predicate symbol.
+  RETURNS: The number of occurrences of the predicate symbol in Term
+**************************************************/			       
+{
+  /* Quantifiers */
+  if (fol_IsQuantifier(term_TopSymbol(Term)))
+    return def_PredicateOccurrences(term_SecondArgument(Term), P);
+
+  /* Junctors and NOT */
+  if (fol_IsJunctor(term_TopSymbol(Term)) ||
+      symbol_Equal(term_TopSymbol(Term),fol_Not())){
+    LIST scan;
+    int count;
+    count = 0;
+    for (scan=term_ArgumentList(Term); !list_Empty(scan); scan=list_Cdr(scan)) {
+      count += def_PredicateOccurrences((TERM) list_Car(scan), P);
+      /* Only the cases count==1 and count>1 are important */
+      if (count > 1)
+	return count;
+    }
+    return count;
+  }
+  
+  if (symbol_Equal(term_TopSymbol(Term), P))
+    return 1;
+  return 0;
+} 
+
+LIST def_ExtractDefsFromTerm(TERM Term, const char* Label) 
+/**************************************************************
+  INPUT:   A term and its label.
+  RETURNS: A list of definitions found in the term.
+  NOTE:    The Term is not changed, the definitions contain copies.
+***************************************************************/
+{
+  TERM andterm;
+  BOOL found;
+  int  pol;
+  LIST univars, termlist, defslist, scan;
+  
+  /* First check if there is a top level and() so that the Term may
+     contain several definitions */
+
+  andterm = Term;
+  found   = FALSE;
+  pol     = 1;
+  univars = list_Nil();
+
+  /* Traverse top down universal quantifiers */
+  while (!found) {
+    if ((symbol_Equal(term_TopSymbol(andterm), fol_All()) && (pol == 1))
+	|| (symbol_Equal(term_TopSymbol(andterm), fol_Exist()) && (pol == -1))) {
+      univars = list_Nconc(univars, list_Copy(fol_QuantifierVariables(andterm)));
+      andterm = term_SecondArgument(andterm);
+    }
+    else {
+      if (symbol_Equal(term_TopSymbol(andterm), fol_Not())) {
+	pol = -pol;
+	andterm = term_FirstArgument(andterm);
+      }
+      else
+	found = TRUE;
+    }
+  }
+
+  termlist = list_Nil();
+  /* Check if conjunction was found */
+  if ((symbol_Equal(term_TopSymbol(andterm), fol_And()) && (pol == 1))
+      || (symbol_Equal(term_TopSymbol(andterm), fol_Or()) && (pol == -1))) {
+    LIST l;
+    /* Flatten nested and/or */
+    /* Make copy of relevant subterm */
+    andterm = cnf_Flatten(term_Copy(andterm), term_TopSymbol(andterm));
+    for (l=term_ArgumentList(andterm); !list_Empty(l); l=list_Cdr(l)) {
+      TERM newterm;
+      newterm = fol_CreateQuantifierAddFather(fol_All(), term_CopyTermList(univars),
+					      list_List(list_Car(l)));
+      termlist = list_Cons(newterm, termlist);
+    }
+    /* Arguments are used in new terms */
+    list_Delete(term_ArgumentList(andterm));
+    term_Free(andterm);
+  }
+  else
+    termlist = list_List(term_Copy(Term));
+  
+  list_Delete(univars);
+
+  /* Now we have a list of terms that may contain definitions */
+  defslist = list_Nil();
+  for (scan=termlist; !list_Empty(scan); scan=list_Cdr(scan)) {
+    TERM cand;
+    TERM foundpred, toprove;
+
+    /* Candidate from list */
+    cand = (TERM) list_Car(scan);
+    term_AddFatherLinks(cand);
+
+    if (cnf_ContainsDefinition(cand, &foundpred)) {
+      DEF def;
+#ifdef CHECK
+      if (!fol_CheckFormula(cand)) {
+	misc_StartErrorReport();
+	misc_ErrorReport("\n In def_ExtractDefsFromTerm: Illegal term cand");
+	misc_FinishErrorReport();
+      }
+#endif
+      cand = cnf_DefConvert(cand, foundpred, &toprove);
+#ifdef CHECK
+      if (!fol_CheckFormula(cand)) {
+	misc_StartErrorReport();
+	misc_ErrorReport("\n In def_ExtractDefsFromTerm: Illegal term cand");
+	misc_FinishErrorReport();
+      }
+#endif
+      def  = def_CreateFromTerm(term_Copy(term_SecondArgument(term_Superterm(foundpred))), 
+				term_Copy(foundpred), toprove, Label);
+
+      if (def_PredicateOccurrences(cand, term_TopSymbol(foundpred)) > 1)
+	def_RemoveAttribute(def, PREDOCCURONCE);
+      else 
+	def_AddAttribute(def, PREDOCCURONCE);
+      if (symbol_Equal(term_TopSymbol(foundpred), fol_Equality()))
+	def_AddAttribute(def, ISEQUALITY);
+      else
+	def_RemoveAttribute(def, ISEQUALITY);
+
+      defslist = list_Cons(def, defslist);
+    }
+    term_Delete(cand);
+  }
+  
+  list_Delete(termlist);
+  return defslist;
+}
+
+void def_ExtractDefsFromClauselist(PROOFSEARCH Search, LIST Clauselist)
+/**************************************************************
+  INPUT:   A proofsearch object and a list of clauses
+  RETURNS: Nothing.
+  EFFECT:  The definitions found in the clauselist object are stored in
+           the proofsearch object.
+  NOTE:    The clause list is not changed.
+           The old list of definitions in the proofsearch object is 
+	   overwritten.
+***************************************************************/
+{
+  LIST       scan, defslist;
+  FLAGSTORE  FlagStore;
+  PRECEDENCE Precedence;
+
+  defslist   = list_Nil();
+  FlagStore  = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+
+  for (scan=Clauselist; !list_Empty(scan); scan=list_Cdr(scan)) {
+    CLAUSE Clause;
+    NAT index;
+    LIST pair;
+
+    Clause = (CLAUSE) list_Car(scan);
+    /* Check if clause contains a predicate that may be part of a definition */
+    if (clause_ContainsPotPredDef(Clause, FlagStore, Precedence, &index, &pair)) {
+      LIST l, compl, compllits;
+      BOOL done;
+
+      compl = compllits = list_Nil();
+      done = FALSE;
+      
+      /* Search for complement clauses */
+      for (l=Clauselist; !list_Empty(l) && !done; l=list_Cdr(l)) {
+	int predindex;
+	if (clause_IsPartOfDefinition((CLAUSE) list_Car(l), 
+				      clause_GetLiteralTerm(Clause, index), 
+				      &predindex, pair)) {
+	  compl     = list_Cons(list_Car(l), compl);
+	  compllits = list_Cons((POINTER) predindex, compllits);
+	  
+	  if (list_Empty(list_PairFirst(pair)) &&
+	      list_Empty(list_PairSecond(pair)))
+	    done = TRUE;
+	}
+      }
+      
+      /* All complements found ? */ 
+      if (done) {
+	LIST l2, clausenumbers, args;
+	DEF  def;
+	NAT  i;
+	TERM defterm, predterm;
+	BOOL con;
+
+	clausenumbers = list_Nil();
+	con           = clause_GetFlag(Clause, CONCLAUSE);
+
+	for (l2=compl; !list_Empty(l2); l2=list_Cdr(l2)) {
+	  clausenumbers = list_Cons((POINTER) clause_Number((CLAUSE) list_Car(l2)), 
+				    clausenumbers);	    
+	  if (clause_GetFlag((CLAUSE) list_Car(l2), CONCLAUSE))
+	    con = TRUE;
+	}
+	clausenumbers = list_Cons((POINTER) clause_Number(Clause), 
+				  clausenumbers);
+	compllits = list_Cons((POINTER) index, compllits);
+
+	/* Build definition term */
+	predterm = term_Copy(clause_GetLiteralTerm(Clause, index));
+	args     = list_Nil();
+	for (i = 0; i < clause_Length(Clause); i++) 
+	  if (i != index)
+	    args = list_Cons(term_Copy(clause_GetLiteralTerm(Clause, i)), args);
+	defterm  = term_CreateAddFather(fol_Or(), args);
+	/* The expansion is negative here, so it must be inverted */
+	defterm  = term_Create(fol_Not(), list_List(defterm));
+	defterm  = cnf_NegationNormalFormula(defterm);
+	def      = def_CreateFromClauses(defterm, predterm, clausenumbers, compllits, con);
+	defslist = list_Cons(def, defslist);
+	if (flag_GetFlagValue(FlagStore, flag_PAPPLYDEFS)) {
+	  fputs("\nNew definition found :", stdout);
+	  def_Print(def);
+	}
+      }
+      else {
+	list_Delete(compllits);
+	list_Delete(list_PairSecond(pair));
+	list_Delete(list_PairFirst(pair));
+      }
+      list_Delete(compl);
+      list_PairFree(pair);
+    }
+  }
+
+  if (flag_GetFlagValue(FlagStore, flag_PAPPLYDEFS)) {
+    if (!list_Empty(defslist)) {
+      fputs("\nFound definitions :\n", stdout);
+      for (scan = defslist; !list_Empty(scan); scan = list_Cdr(scan)) {
+	def_Print((DEF) list_Car(scan));
+	fputs("\n---\n", stdout);
+      }
+    }
+  }
+
+  for (scan=defslist; !list_Empty(scan); scan=list_Cdr(scan))
+    symbol_AddProperty(term_TopSymbol(def_Predicate((DEF) list_Car(scan))), ISDEF);
+  
+  prfs_SetDefinitions(Search, list_Nconc(prfs_Definitions(Search), defslist));
+}
+
+TERM def_ApplyDefToTermOnce(DEF Def, TERM Term, FLAGSTORE FlagStore,
+			    PRECEDENCE Precedence, BOOL* Complete)
+/**************************************************************
+  INPUT:   A DEF structure, a term and a boolean that is set
+           to TRUE if no occurrences of the defined predicate
+	   remain in the term. A flag store and a precedence.
+  RETURNS: A term where all occurrences of the definitions
+           predicate are expanded if possible.
+  NOTE:    The Term is not changed.
+***************************************************************/
+{
+  TERM newtarget, oldtarget, targetpredicate, totoplevel, toprove;
+  LIST targettermvars, varsfortoplevel;
+  BOOL applicable;
+
+  oldtarget = Term;
+  *Complete = TRUE;
+
+  while (TRUE) {
+    newtarget = term_Copy(oldtarget);
+    term_AddFatherLinks(newtarget);
+    targettermvars = varsfortoplevel = list_Nil();
+
+    if (cnf_ContainsPredicate(newtarget, term_TopSymbol(def_Predicate(Def)),
+			      &targetpredicate, &totoplevel, &targettermvars, 
+			      &varsfortoplevel)) {
+      *Complete  = FALSE;
+      applicable = FALSE;
+      /* Check if definition is not always applicable */
+      if (term_Equal(def_ToProve(Def), term_Null())) { 
+	applicable = TRUE;
+	newtarget = cnf_ApplyDefinitionOnce(def_Predicate(Def), term_Copy(def_Expansion(Def)),
+					 newtarget, targetpredicate, FlagStore);
+	if (oldtarget != Term)
+	  term_Delete(oldtarget);
+	oldtarget = newtarget;
+      	list_Delete(targettermvars);
+	list_Delete(varsfortoplevel); 	
+      }
+      else {
+	toprove = term_Copy(def_ToProve(Def));
+	newtarget = cnf_DefTargetConvert(newtarget, totoplevel, toprove,
+					 term_ArgumentList(def_Predicate(Def)),
+					 term_ArgumentList(targetpredicate),
+					 targettermvars, varsfortoplevel,
+					 FlagStore, Precedence,
+					 &applicable);
+	list_Delete(targettermvars);
+	list_Delete(varsfortoplevel); 	
+	if (applicable) {
+	  newtarget = cnf_ApplyDefinitionOnce(def_Predicate(Def), term_Copy(def_Expansion(Def)),
+					   newtarget, targetpredicate, FlagStore);
+	  if (oldtarget != Term)
+	    term_Delete(oldtarget);
+	  oldtarget = newtarget;
+	}
+	else {
+	  /* Predicate still exists but cannot be expanded */
+	  term_Delete(newtarget);
+	  if (oldtarget == Term)
+	    return NULL;
+	  else {
+	    oldtarget = cnf_ObviousSimplifications(oldtarget);
+	    return oldtarget;
+	  }
+	}
+      }
+    }
+    else {
+      *Complete = TRUE;
+      /* Predicate does no longer exist */
+      term_Delete(newtarget);
+      /* No expansion possible */
+      if (oldtarget == Term)
+	return NULL;
+      else {
+	oldtarget = cnf_ObviousSimplifications(oldtarget);
+	return oldtarget;
+      }
+    }
+  }
+  return NULL; /* Unreachable */
+}
+    
+TERM def_ApplyDefToTermExhaustive(PROOFSEARCH Search, TERM Term)
+/**************************************************************
+  INPUT:   A proofsearch object and a term.
+  RETURNS: An expanded term.
+  NOTE:    All occurences of defined predicates are expanded in the term,
+           until no further changes are possible.
+  CAUTION: If cyclic definitions exist, this will crash.
+***************************************************************/
+{
+  TERM       oldterm, newterm;
+  BOOL       done, complete;
+  FLAGSTORE  FlagStore;
+  PRECEDENCE Precedence;
+
+  done       = FALSE;
+  oldterm    = Term;
+  FlagStore  = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+
+  while (!done) {
+    LIST l;
+    done = TRUE;
+    /* Apply all definitions to term until no more changes occur */
+    for (l=prfs_Definitions(Search); !list_Empty(l); l=list_Cdr(l)) {
+      newterm = def_ApplyDefToTermOnce((DEF) list_Car(l), oldterm,
+				       FlagStore, Precedence, &complete);
+      if (newterm != NULL) {
+	if (oldterm != Term)
+	  term_Delete(oldterm);
+	oldterm = newterm;
+	done = FALSE;
+      }
+    }
+  }
+  if (oldterm == Term)
+    return NULL;
+  else
+    return oldterm;
+}
+
+LIST def_ApplyDefToClauseOnce(DEF Def, CLAUSE Clause,
+			      FLAGSTORE FlagStore, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A DEF structure, a clause, a flag store and a
+           precedence.
+  RETURNS: A list of new clauses.
+  NOTE:    The clause is not changed.
+           All occurences of the defined predicate are expanded
+	   in the clause and in the derived clauses.
+***************************************************************/
+{
+  LIST result, l;
+  
+  result = list_List(Clause);
+
+  for (l = result; !list_Empty(l); l = list_Cdr(l)) {
+    if (clause_ContainsSymbol((CLAUSE) list_Car(l), 
+			      term_TopSymbol(def_Predicate(Def)))) {
+      result = list_Nconc(result, 
+			  cnf_ApplyDefinitionToClause((CLAUSE) list_Car(l), 
+						      def_Predicate(Def),
+						      def_Expansion(Def),
+						      FlagStore, Precedence));
+      /* Remove temporary clause */
+      if ((CLAUSE) list_Car(l) != Clause)
+	clause_Delete((CLAUSE) list_Car(l));
+      list_Rplaca(l, NULL);
+    }
+  }
+  result = list_PointerDeleteElement(result, NULL);
+
+  /* Make sure the original clause is no longer in the list */
+  if (!list_Empty(result))
+    if (list_First(result) == Clause)
+      result = list_Pop(result);
+  
+  for (l = result; !list_Empty(l); l=list_Cdr(l)) {
+    CLAUSE c;
+    c = (CLAUSE) list_Car(l);
+    if (def_Conjecture(Def))
+      clause_SetFlag((CLAUSE) list_Car(l), CONCLAUSE);
+    clause_SetFromDefApplication(c);
+    clause_SetParentClauses(c, list_Cons((POINTER) clause_Number(Clause), 
+					 list_Copy(def_ClauseNumberList(Def))));
+    /* Parent literal is not available, as the predicate may occur several 
+       times in the target clause */
+    clause_SetParentLiterals(c, list_Cons((POINTER) 0, 
+					  list_Copy(def_ClauseLitsList(Def))));
+  }
+  return result;
+}
+
+LIST def_ApplyDefToClauseExhaustive(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A proofsearch object and a clause.
+  RETURNS: A list of derived clauses.
+  NOTE:    All occurences of defined predicates are expanded in the clause.
+           until no further changes are possible.
+  CAUTION: If cyclic definitions exist, this will crash.
+***************************************************************/
+{
+  LIST       newclauses, scan, result;
+  CLAUSE     orig;
+  FLAGSTORE  FlagStore;
+  PRECEDENCE Precedence;
+
+  orig       = clause_Copy(Clause);
+  newclauses = list_List(orig);
+  result     = list_Nil();
+  FlagStore  = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+
+  while (!list_Empty(newclauses)) {
+    /* Check all clauses */
+    LIST l, nextlist;
+
+    /* List of clauses derived from newclauses by expanding predicates */
+    nextlist = list_Nil();
+
+    for (l=newclauses; !list_Empty(l); l=list_Cdr(l)) {
+      LIST clauses;
+      CLAUSE c;
+      
+      c = (CLAUSE) list_Car(l);
+
+      /* Apply all definitions to the clause */
+
+      /* List of clauses derived from one clause in newclauses by */
+      /* expanding all possible predicates */
+      clauses  = list_Nil();
+
+      for (scan=prfs_Definitions(Search); !list_Empty(scan); scan=list_Cdr(scan))
+	clauses = list_Nconc(clauses, def_ApplyDefToClauseOnce((DEF) list_Car(scan), c, FlagStore, Precedence));
+      
+      /* If expansions were made delete old clause */
+      if (!list_Empty(clauses)) {
+	/* DOCPROOF ? */
+	if (c != Clause) {
+	  if (flag_GetFlagValue(FlagStore, flag_DOCPROOF)) {
+	    prfs_InsertDocProofClause(Search, c);
+	  }
+	  else
+	    clause_Delete(c);
+	}
+	nextlist = list_Nconc(nextlist, clauses);
+      }
+      else {
+	/* No more expansions possible for this clause */
+	/* If it is not the original clause, add it to the result list */
+	if (c != Clause)
+	  result = list_Cons(c, result);
+      }
+    }
+    list_Delete(newclauses);
+    newclauses = nextlist;
+  }
+      
+  return result;
+}
+  
+
+void def_Print(DEF D)
+/**************************************************************
+  INPUT:   A DEF structure.
+  RETURNS: None.
+  EFFECT:  Prints the definition to stdout. 
+***************************************************************/
+{
+  LIST scan, scan2;
+  fputs("\n\nAtom: ", stdout);
+  fol_PrettyPrint(def_Predicate(D));
+  fputs("\nExpansion: \n", stdout);
+  fol_PrettyPrint(def_Expansion(D));
+  if (!list_Empty(def_ClauseNumberList(D))) {
+    fputs("\nParent clauses: ", stdout);
+    for (scan = def_ClauseNumberList(D), scan2 = def_ClauseLitsList(D); 
+	 !list_Empty(scan); scan = list_Cdr(scan), scan2 = list_Cdr(scan2)) 
+      printf("%d.%d ", (NAT) list_Car(scan), (NAT) list_Car(scan2));
+    if (D->conjecture)
+      fputs("\nDerived from conjecture clauses.", stdout);
+    else
+      fputs("\nNot derived from conjecture clauses.", stdout);
+  }
+  else {
+    fputs("\nLabel: ", stdout);
+    fputs(def_Label(D), stdout);
+    puts("\nGuard:");
+    if (def_ToProve(D) != NULL) 
+      fol_PrettyPrint(def_ToProve(D));
+    else
+      fputs("Nothing.", stdout);
+  }
+
+  fputs("\nAttributes: ", stdout);
+  if (def_HasAttribute(D, ISEQUALITY) || def_HasAttribute(D, PREDOCCURONCE)) {
+    if (def_HasAttribute(D, ISEQUALITY))
+      fputs(" Equality ", stdout);
+    if (def_HasAttribute(D, PREDOCCURONCE))
+      fputs(" No Multiple Occurrences ", stdout);
+  }
+  else {
+    fputs(" None ", stdout);
+  }    
+} 
+
+LIST def_ApplyDefToClauselist(PROOFSEARCH Search, DEF Def, 
+			      LIST Clauselist, BOOL Destructive)
+/**************************************************************
+  INPUT:   A proofsearch object, a DEF structure, a list of unshared clauses
+           and a boolean saying whether the parent clause of an expansion
+	   should be deleted.
+  RETURNS: None.
+  EFFECT:  For each occurrence of the defined predicate in a clause in the list,
+  a new clause with expanded predicate is added to the list.
+***************************************************************/
+{
+  LIST       l, newclauses, allnew;
+  FLAGSTORE  FlagStore;
+  PRECEDENCE Precedence;
+
+  allnew     = list_Nil();
+  FlagStore  = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+
+  for (l = Clauselist; !list_Empty(l); l = list_Cdr(l)) {
+    newclauses = def_ApplyDefToClauseOnce(Def, (CLAUSE) list_Car(l),
+					  FlagStore, Precedence);
+    /* Expansions were possible, delete the original clause */
+    if (Destructive && !list_Empty(newclauses)) {
+      if (flag_GetFlagValue(FlagStore, flag_DOCPROOF))
+	prfs_InsertDocProofClause(Search, (CLAUSE) list_Car(l));
+      else
+	clause_Delete((CLAUSE) list_Car(l));
+      list_Rplaca(l, NULL);
+    }
+    allnew = list_Nconc(allnew, newclauses);
+  }
+  if (Destructive)
+    Clauselist = list_PointerDeleteElement(Clauselist, NULL);
+
+
+  if (flag_GetFlagValue(FlagStore, flag_PAPPLYDEFS)) {
+    if (!list_Empty(allnew)) {
+      fputs("\nNew clauses after applying definitions : \n", stdout);
+      clause_ListPrint(allnew);
+    }
+  }
+
+  Clauselist = list_Nconc(Clauselist, allnew);
+  return Clauselist;
+}
+
+LIST def_ApplyDefToTermlist(DEF Def, LIST Termlist,
+			    FLAGSTORE FlagStore, PRECEDENCE Precedence,
+			    BOOL* Complete, BOOL Destructive)
+/**************************************************************
+  INPUT:   A DEF structure and a list of pairs (label, term),
+           a flag store, a precedence and a pointer to a
+	   boolean.
+	   If Destructive is TRUE the father of an expanded
+	   term is deleted.
+  RETURNS: The changed list of terms.
+  EFFECT:  For each occurrence of the defined predicate in a
+           term in the list, a new term with expanded predicate
+	   is added to the list.
+	   If every occurrence of the predicate could be
+	   expanded, Complete is set to TRUE.
+***************************************************************/
+{
+  LIST l, newterms;
+  
+  newterms = list_Nil();
+
+  *Complete = TRUE;
+  for (l=Termlist; !list_Empty(l); l=list_Cdr(l)) {
+    TERM newterm;
+    TERM oldterm;
+    BOOL complete;
+    oldterm = list_PairSecond(list_Car(l));
+    newterm = def_ApplyDefToTermOnce(Def, oldterm, FlagStore,
+				     Precedence, &complete);
+    if (!complete)
+      *Complete = FALSE;
+    /* destructive part of function */
+    if (newterm != NULL) {
+      newterms = list_Cons(list_PairCreate(NULL, newterm),newterms);
+      if (Destructive) {
+	/* Delete oldterm from Termlist */
+	term_Delete(list_PairSecond(list_Car(l)));
+	if (list_PairFirst(list_Car(l)) != NULL)
+	  string_StringFree(list_PairFirst(list_Car(l)));
+	
+	list_PairFree(list_Car(l));
+	list_Rplaca(l, NULL);
+      }
+    }
+  }
+  Termlist = list_PointerDeleteElement(Termlist, NULL);
+
+  if (flag_GetFlagValue(FlagStore, flag_PAPPLYDEFS)) {
+    if (!list_Empty(newterms)) {
+      fputs("\n\nNew terms after applying definitions : \n", stdout);
+      for (l=newterms; !list_Empty(l); l=list_Cdr(l)) {
+	fputs("\n", stdout);
+	fol_PrettyPrint(list_PairSecond(list_Car(l)));
+      }
+    }
+  }
+  
+  Termlist = list_Nconc(Termlist, newterms);
+  return Termlist;
+}
+
+void def_ExtractDefsFromTermlist(PROOFSEARCH Search, LIST Axioms, LIST Conj)
+/**************************************************************
+  INPUT:   A proofsearch object and 2 lists of pairs label/term.
+  RETURNS: None.
+  EFFECT:  Add all found definitions to the proofsearch object.
+           The old list of definitions in the proofsearch object is 
+	   overwritten.
+***************************************************************/
+{ 
+  LIST      l, deflist;
+  FLAGSTORE FlagStore;
+
+  deflist   = list_Nil();
+  FlagStore = prfs_Store(Search);
+
+  for (l=Axioms; !list_Empty(l); l=list_Cdr(l)) {
+    fol_NormalizeVars(list_PairSecond(list_Car(l))); /* Is needed for proper variable match ! */
+    deflist = list_Nconc(deflist,
+			 def_ExtractDefsFromTerm(list_PairSecond(list_Car(l)),
+						 list_PairFirst(list_Car(l))));
+  }
+  for (l=Conj; !list_Empty(l); l=list_Cdr(l)) {
+    fol_NormalizeVars(list_PairSecond(list_Car(l))); /* Is needed for proper variable match ! */
+    deflist = list_Nconc(deflist,
+			 def_ExtractDefsFromTerm(list_PairSecond(list_Car(l)),
+						 list_PairFirst(list_Car(l))));
+  }
+  for (l=deflist; !list_Empty(l); l=list_Cdr(l))
+    symbol_AddProperty(term_TopSymbol(def_Predicate(list_Car(l))), ISDEF);
+
+  prfs_SetDefinitions(Search, list_Nconc(prfs_Definitions(Search), deflist));  
+
+  if (flag_GetFlagValue(FlagStore, flag_PAPPLYDEFS)) {
+    if (!list_Empty(deflist)) {
+      fputs("\nFound definitions :\n", stdout);
+      for (l = prfs_Definitions(Search); !list_Empty(l); l = list_Cdr(l)) {
+	def_Print(list_Car(l));
+	fputs("\n---\n", stdout);
+      }
+    }
+  }
+}
+
+LIST def_FlattenWithOneDefinition(PROOFSEARCH Search, DEF Def)
+/**************************************************************
+  INPUT:   A proofsearch object and one definition.
+  RETURNS: The list of new definitions.
+  EFFECT:  For every occurrence of the defined predicate among the other
+           definitions an expansion is attempted.
+	   A new definition is only created if the result of the expansion is 
+	   again a definition. 
+	   The proofsearch object is not changed.
+***************************************************************/
+{
+  LIST       newdefinitions;
+  FLAGSTORE  FlagStore;
+  PRECEDENCE Precedence;
+
+  newdefinitions = list_Nil();
+  FlagStore      = prfs_Store(Search);
+  Precedence     = prfs_Precedence(Search);
+
+  if (def_ToProve(Def) == NULL) {
+    LIST definitions, l;
+
+    definitions = prfs_Definitions(Search);
+
+    for (l = definitions; !list_Empty(l); l=list_Cdr(l)) {
+      DEF d;
+
+      d = (DEF) list_Car(l);      
+      if (d != Def) {
+	/* Expansion possible */
+	if (term_ContainsSymbol(def_Expansion(d), term_TopSymbol(def_Predicate(Def)))) {
+	  /* Resulting term is still a definition */
+	  if (!term_ContainsSymbol(def_Expansion(Def), term_TopSymbol(def_Predicate(d)))) {
+	    TERM newexpansion;
+	    BOOL complete;
+	    DEF newdef;
+	    newexpansion = def_ApplyDefToTermOnce(Def, def_Expansion(d),
+						  FlagStore, Precedence,
+						  &complete);
+	    
+	    newdef = def_CreateFromTerm(newexpansion,
+					term_Copy(def_Predicate(d)), 
+					term_Copy(def_ToProve(d)), def_Label(d));
+	    newdefinitions = list_Cons(newdef, newdefinitions);
+	  }
+	}
+      }
+      
+    }
+  }
+  return newdefinitions;
+}
+
+
+void def_FlattenWithOneDefinitionDestructive(PROOFSEARCH Search, DEF Def)
+/**************************************************************
+  INPUT:   A proofsearch object and one definition.
+  RETURNS: None.
+  EFFECT:  If the definition is always applicable, every occurrence of the 
+           defined predicate among the other definitions is expanded in place.
+	   If the resulting term is no longer a definition, it is deleted from
+	   the proofsearch object.
+	   Def is deleted.
+  CAUTION: This function changes the list entries in the list of definitions 
+           in the proofsearch object, so do not call it from a loop over
+           all definitions.
+***************************************************************/
+{
+  FLAGSTORE  FlagStore;
+  PRECEDENCE Precedence;
+
+  FlagStore  = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+
+  if (def_ToProve(Def) == NULL) {
+    LIST definitions, l;
+
+    definitions = prfs_Definitions(Search);    
+    for (l = definitions; !list_Empty(l); l = list_Cdr(l)) {
+      DEF d;
+
+      d = (DEF) list_Car(l);      
+      if (d != Def) {
+	/* Expansion possible */
+	if (term_ContainsSymbol(def_Expansion(d), term_TopSymbol(def_Predicate(Def)))) {
+	  /* Resulting term is still a definition */
+	  if (!term_ContainsSymbol(def_Expansion(Def), term_TopSymbol(def_Predicate(d)))) {
+	    TERM newexpansion;
+	    BOOL complete;
+
+	    newexpansion = def_ApplyDefToTermOnce(Def, def_Expansion(d), FlagStore, Precedence, &complete);
+	    term_Delete(def_Expansion(d));
+	    def_RplacExp(d, newexpansion);
+	  }
+	  else {
+	    symbol_RemoveProperty(term_TopSymbol(def_Predicate(d)), ISDEF);
+	    def_Delete(d);
+	    list_Rplaca(l, NULL);
+	  }
+	}
+      }
+      else {
+	/* Remove given definition */
+	list_Rplaca(l, NULL);
+      }
+    }
+    symbol_RemoveProperty(term_TopSymbol(def_Predicate(Def)), ISDEF);
+    def_Delete(Def);
+    definitions = list_PointerDeleteElement(definitions, NULL);
+    prfs_SetDefinitions(Search, definitions);
+  }
+}
+
+void def_FlattenWithOneDefinitionSemiDestructive(PROOFSEARCH Search, DEF Def)
+/**************************************************************
+  INPUT:   A proofsearch object and one definition.
+  RETURNS: Nothing.
+  EFFECT:  If the definition can be applied to another definition
+           in the search object, that definition is destructively changed.
+	   If the resulting term is no longer a definition, it is deleted to
+	   prevent cycles.
+	   The applied definition Def is NOT deleted.
+  CAUTION: After calling this function some entries of the definitions list
+           in the proofsearch object may be NULL.
+***************************************************************/
+{
+  FLAGSTORE  FlagStore;
+  PRECEDENCE Precedence;
+
+  FlagStore  = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+  
+  if (def_ToProve(Def) == NULL) {
+    LIST definitions, l;
+
+    definitions = prfs_Definitions(Search);    
+    for (l = definitions; !list_Empty(l); l=list_Cdr(l)) {
+      DEF d;
+
+      d = (DEF) list_Car(l);      
+      if (d != Def) {
+	/* Expansion possible */
+	if (term_ContainsSymbol(def_Expansion(d), term_TopSymbol(def_Predicate(Def)))) {
+	  /* Resulting term is still a definition */
+	  if (!term_ContainsSymbol(def_Expansion(Def), term_TopSymbol(def_Predicate(d)))) {
+	    TERM newexpansion;
+	    BOOL complete;
+
+	    newexpansion = def_ApplyDefToTermOnce(Def, def_Expansion(d),
+						  FlagStore, Precedence,
+						  &complete);
+	    term_Delete(def_Expansion(d));
+	    def_RplacExp(d, newexpansion);
+	  }
+	  else {
+	    symbol_RemoveProperty(term_TopSymbol(def_Predicate(d)), ISDEF);
+	    def_Delete(d);
+	    list_Rplaca(l, NULL);
+	  }
+	}
+      }
+    }
+  }
+}
+
+void def_FlattenDefinitionsDestructive(PROOFSEARCH Search)
+/**************************************************************
+  INPUT:   A proofsearch object.
+  RETURNS: None.
+  EFFECT:  For every definition that is always applicable try to 
+           expand the predicate in other
+           definitions if possible.
+***************************************************************/
+{
+  LIST l;
+
+  for (l = prfs_Definitions(Search); !list_Empty(l); l=list_Cdr(l)) {
+    DEF d;
+
+    d = (DEF) list_Car(l);
+    fol_PrettyPrintDFG(def_Predicate(d));
+    if (d != NULL)
+      def_FlattenWithOneDefinitionSemiDestructive(Search, d);
+  }
+  prfs_SetDefinitions(Search, list_PointerDeleteElement(prfs_Definitions(Search), NULL));
+}
+
+LIST def_GetTermsForProof(TERM Term, TERM SubTerm, int Polarity)
+/**************************************************************
+  INPUT:   Two formulas, <Term> and <SubTerm> which must be subformula
+           of <Term>,an int which is the polarity of <SubTerm> in its
+	   superterm and a list of variables <Variables>.
+  RETURN:  A list of formulas that are used to prove the guard of Atom.
+  COMMENT: Helpfunction of def_FindProofFor Guard.
+  CAUTION: Father links must be set. Free variables may exist in terms of
+           return list.
+	   Terms are copied.
+***************************************************************/
+{
+  TERM   SuperTerm, AddToList;
+  SYMBOL Top;
+  LIST   Scan1, NewList;
+
+  term_AddFatherLinks(Term);
+
+#ifdef CHECK
+  if (!fol_CheckFormula(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In def_GetTermsForProof: Illegal input Term.");
+    misc_FinishErrorReport();
+  } 
+#endif
+
+  if (Term == SubTerm)
+    return list_Nil();
+
+  SuperTerm = term_Superterm(SubTerm);
+  Top       = term_TopSymbol(SuperTerm);
+  NewList   = list_Nil();
+  AddToList = term_Null();
+
+  if (symbol_Equal(Top, fol_Not()))
+    return def_GetTermsForProof(Term, SuperTerm, -1*Polarity);
+
+  if (symbol_Equal(Top, fol_Or()) && Polarity == 1) {
+    /* Get and store AddToList */
+    for (Scan1 = term_ArgumentList(SuperTerm); !list_Empty(Scan1); Scan1 = list_Cdr(Scan1)) {
+      if (!term_HasPointerSubterm(list_Car(Scan1), SubTerm))
+	NewList = list_Cons(term_Create(fol_Not(),list_List(term_Copy(list_Car(Scan1)))), NewList);
+      /* NewList's elements have the form not(term) */
+    }
+    if (list_Length(NewList) == 1) {
+      AddToList = list_Car(NewList);
+      list_Delete(NewList);
+    }
+    else {
+      AddToList = term_Create(fol_And(), NewList);
+    }
+    return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, Polarity));
+  }
+  if (symbol_Equal(Top, fol_And()) && Polarity == -1) {
+    /* Get and store AddToList */
+    if (list_Length(term_ArgumentList(SuperTerm)) == 2) {
+      if (!term_HasPointerSubterm(term_FirstArgument(SuperTerm), SubTerm)) {
+	AddToList = term_Copy(term_FirstArgument(SuperTerm));
+      }
+      else {
+	AddToList = term_Copy(term_SecondArgument(SuperTerm));
+      }
+    }
+    else if (list_Length(term_ArgumentList(SuperTerm)) > 2) {
+      for (Scan1 = term_ArgumentList(SuperTerm); !list_Empty(Scan1); Scan1 = list_Cdr(Scan1)) {
+	if (!term_HasPointerSubterm(list_Car(Scan1), SubTerm))
+	  NewList = list_Cons(term_Copy(list_Car(Scan1)), NewList);
+      }
+      AddToList = term_Create(fol_And(), NewList);
+    }
+    else { /* Only one argument */
+      AddToList = term_Copy(term_FirstArgument(SuperTerm));
+    }
+   return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, Polarity));
+  }
+  if (symbol_Equal(Top, fol_Implies())) {
+    if (term_HasPointerSubterm(term_SecondArgument(SuperTerm), SubTerm) && Polarity == 1) {
+      AddToList = term_Copy(term_FirstArgument(SuperTerm));
+      return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, Polarity));
+    }
+    if (term_HasPointerSubterm(term_FirstArgument(SuperTerm), SubTerm) && Polarity == -1) {
+      AddToList = term_Copy(term_SecondArgument(SuperTerm));
+      AddToList = term_Create(fol_Not(), list_List(AddToList));
+      return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, -1*Polarity));
+    }
+  }
+  if (symbol_Equal(Top, fol_Implied())) { /* symmetric to fol_Implies */
+    if (term_HasPointerSubterm(term_SecondArgument(SuperTerm), SubTerm) && Polarity == -1) {
+      AddToList = term_Copy(term_FirstArgument(SuperTerm));
+      AddToList = term_Create(fol_Not(), list_List(AddToList));
+      return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, -1*Polarity)); 
+    }
+    if (term_HasPointerSubterm(term_FirstArgument(SuperTerm), SubTerm) && Polarity == 1) {
+      AddToList = term_Copy(term_SecondArgument(SuperTerm));
+      return list_Cons(AddToList, def_GetTermsForProof(Term, SuperTerm, Polarity));
+    }
+  }
+  if (fol_IsQuantifier(Top))
+    return def_GetTermsForProof(Term, SuperTerm, Polarity);
+
+  /* In all other cases, SubTerm is the top level term in which Atom occurs disjunctively */
+
+  return list_Nil();
+}
+
+BOOL def_FindProofForGuard(TERM Term, TERM Atom, TERM Guard, FLAGSTORE FlagStore, PRECEDENCE Precedence)
+/**************************************************************************
+  INPUT:   A formula Term, an atom Atom, a term Guard a flag store and a 
+           precedence.
+  RETURNS: True iff a proof can be found for Guard in Term.
+***************************************************************************/
+{
+  BOOL LocallyTrue;
+  TERM ToProve, Conjecture;
+  LIST ArgList, FreeVars;
+
+  ArgList    = list_Nil();
+  FreeVars   = list_Nil();
+  ToProve    = term_Null();
+  Conjecture = term_Copy(Term);
+
+#ifdef CHECK
+  if (!fol_CheckFormula(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In def_FindProofForGuard: No correct formula term.");
+    misc_FinishErrorReport();
+  }
+  if (!term_HasPointerSubterm(Term, Atom)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In def_FindProofForGuard: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  ArgList = def_GetTermsForProof(Term, Atom, 1);
+
+  if (!list_Empty(ArgList)) {
+    ToProve  = term_Create(fol_And(), ArgList);
+    FreeVars = list_Nconc(fol_FreeVariables(ToProve), fol_FreeVariables(Guard));
+    FreeVars = term_DeleteDuplicatesFromList(FreeVars);
+    term_CopyTermsInList(FreeVars);
+
+    ArgList  = list_List(term_Copy(Guard));
+    ArgList  = list_Cons(ToProve, ArgList);
+    ToProve  = term_Create(fol_Implies(), ArgList);
+    ToProve  = fol_CreateQuantifier(fol_All(), FreeVars, list_List(ToProve));
+
+    /* Now ToProve has the form <forall[]: A implies Guard> */
+    /*    puts("\n*ToProve: "); fol_PrettyPrintDFG(ToProve); */
+
+#ifdef CHECK
+    if (!fol_CheckFormula(ToProve)) {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In def_FindProofForGuard: No correct formula ToProve.");
+      misc_FinishErrorReport();
+    }
+#endif
+
+    LocallyTrue = cnf_HaveProof(list_Nil(), ToProve, FlagStore, Precedence);
+    term_Delete(ToProve);
+    term_Delete(Conjecture);
+    if (LocallyTrue)
+      return TRUE;
+  }
+  else {    /* empty list */
+    term_DeleteTermList(ArgList);
+    term_Delete(Conjecture);
+  }
+
+  return FALSE;
+}
+
+LIST def_ApplyDefinitionToTermList(LIST Defs, LIST Terms,
+				   FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************************
+  INPUT:   A list of definitions <Defs> and a list of pairs (Label.Formula),
+           the maximal number <Applics> of expansions, a flag store and a
+	   precedence.
+  RETURNS: The possibly destructively changed list <Terms>.
+  EFFECT:  In all formulas of Terms any definition of Defs is applied exactly
+           once if possible.
+           The terms are changed destructively if the expanded def_predicate 
+	   is not an equality.
+**************************************************************************/
+{
+  TERM ActTerm;             /* Actual term in Terms */
+  TERM DefPredicate;        /* Actual definition predicate out of Defs */
+  TERM Expansion;           /* Expansion term of the definition */
+  TERM Target;              /* Target predicate to be replaced */
+  LIST TargetList, Scan1, Scan2, Scan3;
+  BOOL Apply;
+  int  Applics;
+
+  Apply      = TRUE;
+  TargetList = list_Nil();
+  Applics    = flag_GetFlagValue(Flags, flag_APPLYDEFS);
+
+  while (Apply && Applics != 0) {
+    Apply = FALSE;
+    
+    for (Scan1=Defs; !list_Empty(Scan1) && Applics != 0; Scan1=list_Cdr(Scan1)) {
+      DefPredicate = term_Copy(def_Predicate(list_Car(Scan1)));
+
+      /*      puts("\n----\nDefPred:"); fol_PrettyPrintDFG(DefPredicate);*/
+
+      for (Scan2=Terms; !list_Empty(Scan2) && Applics != 0; Scan2=list_Cdr(Scan2)) {
+	ActTerm   = list_PairSecond(list_Car(Scan2));
+	TargetList = term_FindAllAtoms(ActTerm, term_TopSymbol(DefPredicate));
+	term_AddFatherLinks(ActTerm);
+	
+	/*	puts("\nActTerm:"); fol_PrettyPrintDFG(ActTerm);*/
+
+	for (Scan3=TargetList; !list_Empty(Scan3) && Applics != 0; Scan3=list_Cdr(Scan3)) {
+	  Target = list_Car(Scan3);
+	  cont_StartBinding();
+
+	  /*	  puts("\nTarget:"); fol_PrettyPrintDFG(Target);*/
+
+	  if (unify_Match(cont_LeftContext(), DefPredicate, Target)) {
+	    cont_BackTrack();
+	    Expansion = term_Copy(def_Expansion(list_Car(Scan1)));
+	    fol_NormalizeVarsStartingAt(ActTerm, term_MaxVar(Expansion));
+	    unify_Match(cont_LeftContext(), DefPredicate, Target);
+
+	    if (fol_ApplyContextToTerm(cont_LeftContext(), Expansion)) { /* Matcher applied on Expansion */
+	      if (!def_HasGuard(list_Car(Scan1))) {
+		Applics--;
+		Apply = TRUE;
+		/*		puts("\n*no Guard!");*/
+		term_RplacTop(Target, term_TopSymbol(Expansion));
+		term_DeleteTermList(term_ArgumentList(Target));
+		term_RplacArgumentList(Target, term_ArgumentList(Expansion));
+		term_RplacArgumentList(Expansion, list_Nil());
+		term_AddFatherLinks(ActTerm);
+#ifdef CHECK
+		if (!fol_CheckFormula(ActTerm)) {
+		  misc_StartErrorReport();
+		  misc_ErrorReport("\n In def_ApplyDefinitionToTermList:");
+		  misc_ErrorReport(" No correct formula ActTerm.");
+		  misc_FinishErrorReport();
+		}
+#endif
+		if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) {
+		  puts("\nApplied definition for");
+		  fol_PrettyPrintDFG(def_Predicate(list_Car(Scan1)));
+		  puts("\nNew formula:");
+		  fol_PrettyPrintDFG(ActTerm);
+		}
+	      }
+	      else {  /* check guard */
+		TERM Guard;
+		Guard = term_Copy(def_ToProve(list_Car(Scan1)));
+		if (fol_ApplyContextToTerm(cont_LeftContext(), Guard)) {
+		  cont_BackTrack(); 
+		  if (def_FindProofForGuard(ActTerm, Target,Guard,
+					    Flags, Precedence)) {
+		    Applics--;
+		    Apply = TRUE;
+		    term_RplacTop(Target, term_TopSymbol(Expansion));
+		    term_DeleteTermList(term_ArgumentList(Target));
+		    term_RplacArgumentList(Target, term_ArgumentList(Expansion));
+		    term_RplacArgumentList(Expansion, list_Nil());
+		    term_AddFatherLinks(ActTerm);
+#ifdef CHECK
+		    if (!fol_CheckFormula(ActTerm)) {
+		      misc_StartErrorReport();
+		      misc_ErrorReport("\n In def_ApplyDefinitionToTermList:");
+		      misc_ErrorReport(" No correct formula ActTerm");
+		      misc_FinishErrorReport();
+		    }
+#endif
+		    if (flag_GetFlagValue(Flags, flag_PAPPLYDEFS)) {
+		      puts("\nApplied definition for");
+		      fol_PrettyPrintDFG(def_Predicate(list_Car(Scan1)));
+		      puts("\nNew formula:");
+		      fol_PrettyPrintDFG(ActTerm);
+		    }
+		  }
+		}
+		term_Delete(Guard);
+	      }
+	    }
+	    term_Delete(Expansion);	    
+	  }
+	  cont_BackTrack();
+	}
+	list_Delete(TargetList);
+      }
+      term_Delete(DefPredicate);
+    }
+  }
+  return Terms;
+}
diff --git a/test/spass/defs.h b/test/spass/defs.h
new file mode 100644
index 0000000000000000000000000000000000000000..e3cdd2dcd9e19a6fca9dd550de98c924e4c035ee
--- /dev/null
+++ b/test/spass/defs.h
@@ -0,0 +1,205 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                     Definitions                        * */
+/* *                                                        * */
+/* *  $Module:   DEFS                                       * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1998, 1999, 2000, 2001                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _DEFS_
+#define _DEFS_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+
+#include "clause.h"
+#include "term.h"
+#include "list.h"
+#include "search.h"
+
+/**************************************************************/
+/* Structures                                                 */
+/**************************************************************/
+typedef enum { PREDOCCURONCE = 1, /* whether predicate occurs only once */
+               ISEQUALITY    = 2  /* whether predicate is equality */
+} DEF_ATTRIBUTES;
+
+typedef struct DEF_HELP {
+  TERM   expansion;        /* The definition of the predicate term*/
+  TERM   predicate;        /* The predicate which is defined*/
+  TERM   toprove;
+  LIST   parentclauses;    /* List of clause numbers plus list of literal indices */
+  const char *label;            /* The label of the predicate term*/
+  BOOL   conjecture;
+  NAT    attributes;       /* The attributes of the predicate*/
+} *DEF, DEF_NODE;
+
+/**************************************************************/
+/* Inline functions                                           */
+/**************************************************************/
+static __inline__ TERM def_Expansion(DEF D)
+{
+  return D->expansion;
+}
+
+static __inline__ void def_RplacExp(DEF D, TERM E)
+{
+  D->expansion = E;
+}
+
+static __inline__ TERM def_Predicate(DEF D)
+{
+  return D->predicate;
+}
+
+static __inline__ void def_RplacPred(DEF D, TERM Pred)
+{
+  D->predicate = Pred;
+}
+
+static __inline__ TERM def_ToProve(DEF D)
+{
+  return D->toprove;
+}
+
+static __inline__ void def_RplacToProve(DEF D, TERM ToProve)
+{
+  D->toprove = ToProve;
+}
+
+static __inline__ LIST def_ClauseNumberList(DEF D)
+{
+  return list_PairFirst(D->parentclauses);
+}
+
+static __inline__ void def_RplacClauseNumberList(DEF D, LIST L)
+{
+  list_Rplaca(D->parentclauses, L);
+}
+
+static __inline__ LIST def_ClauseLitsList(DEF D)
+{
+  return list_PairSecond(D->parentclauses);
+}
+
+static __inline__ void def_RplacClauseLitsList(DEF D, LIST L)
+{
+  list_Rplacd(D->parentclauses, L);
+}
+
+static __inline__ const char* def_Label(DEF D)
+{
+  return D->label;
+}
+
+static __inline__ void def_RplacLabel(DEF D, const char* L)
+{
+  D->label = L;
+}
+
+static __inline__ BOOL def_Conjecture(DEF D)
+{
+  return D->conjecture;
+}
+
+static __inline__ void def_SetConjecture(DEF D)
+{
+  D->conjecture = TRUE;
+}
+
+static __inline__ void def_AddAttribute(DEF D, DEF_ATTRIBUTES Attribute)
+{
+  D->attributes = D->attributes | Attribute;
+}
+
+static __inline__ NAT def_HasAttribute(DEF D, DEF_ATTRIBUTES Attribute)
+{
+  return (D->attributes & Attribute);
+}
+
+static __inline__ void def_RemoveAttribute(DEF D, DEF_ATTRIBUTES Attribute)
+{
+  if (D->attributes & Attribute)
+    D->attributes = D->attributes - Attribute;
+}
+
+static __inline__ BOOL def_HasGuard(DEF D)
+{
+  return (def_ToProve(D)!=term_Null());
+}
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+DEF  def_CreateFromClauses(TERM, TERM, LIST, LIST, BOOL);
+DEF  def_CreateFromTerm(TERM, TERM, TERM, const char*);
+
+LIST def_ExtractDefsFromTerm(TERM, const char*);
+void def_ExtractDefsFromTermlist(PROOFSEARCH, LIST, LIST);
+void def_ExtractDefsFromClauselist(PROOFSEARCH, LIST);
+
+TERM def_ApplyDefToTermOnce(DEF, TERM, FLAGSTORE, PRECEDENCE, BOOL*);
+TERM def_ApplyDefToTermExhaustive(PROOFSEARCH, TERM);
+LIST def_ApplyDefToTermlist(DEF, LIST, FLAGSTORE, PRECEDENCE, BOOL*, BOOL);
+LIST def_ApplyDefinitionToTermList(LIST, LIST, FLAGSTORE, PRECEDENCE);
+/*
+LIST def_GetTermsForProof(TERM, TERM, int);
+BOOL def_FindProofForGuard(TERM, TERM, TERM, FLAGSTORE);
+*/
+
+LIST def_ApplyDefToClauseOnce(DEF, CLAUSE, FLAGSTORE, PRECEDENCE);
+LIST def_ApplyDefToClauseExhaustive(PROOFSEARCH, CLAUSE);
+LIST def_ApplyDefToClauselist(PROOFSEARCH, DEF, LIST, BOOL);
+
+LIST def_FlattenWithOneDefinition(PROOFSEARCH, DEF);
+void def_FlattenWithOneDefinitionSemiDestructive(PROOFSEARCH, DEF);
+void def_FlattenWithOneDefinitionDestructive(PROOFSEARCH, DEF);
+void def_FlattenDefinitionsDestructive(PROOFSEARCH);
+
+void def_Delete(DEF);
+void def_Print(DEF);
+
+int  def_PredicateOccurrences(TERM, SYMBOL);
+#endif
diff --git a/test/spass/dfg.h b/test/spass/dfg.h
new file mode 100644
index 0000000000000000000000000000000000000000..83d38ae715ce72ce77d090fe25df8ff1ab8b81c9
--- /dev/null
+++ b/test/spass/dfg.h
@@ -0,0 +1,86 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *              INTERFACE FOR THE DFG PARSER              * */
+/* *                                                        * */
+/* *  $Module:   DFG                                        * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1997, 1999, 2000, 2001                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _DFG_
+#define _DFG_
+
+#include <stdio.h>
+#include "list.h"
+#include "flags.h"
+#include "clause.h"
+
+typedef enum { DFG_SATISFIABLE, DFG_UNSATISFIABLE, DFG_UNKNOWNSTATE } DFG_STATE;
+
+/* Parser functions */
+LIST        dfg_DFGParser(FILE*, FLAGSTORE, PRECEDENCE, LIST*, LIST*, LIST*, LIST*);
+LIST        dfg_ProofParser(FILE*, FLAGSTORE, PRECEDENCE);
+LIST        dfg_TermParser(FILE*, FLAGSTORE, PRECEDENCE);
+
+
+/* Functions for accessing description information */
+const char* dfg_ProblemName(void);
+const char* dfg_ProblemAuthor(void);
+const char* dfg_ProblemVersion(void);
+const char* dfg_ProblemLogic(void);
+DFG_STATE   dfg_ProblemStatus(void);
+const char* dfg_ProblemStatusString(void);
+const char* dfg_ProblemDescription(void);
+const char* dfg_ProblemDate(void);
+NAT         dfg_DescriptionLength(void);
+
+/* Misc functions */
+void        dfg_Free(void);   /* Must be called after each parser call */
+void        dfg_DeleteFormulaPairList(LIST);
+void        dfg_StripLabelsFromList(LIST);
+void        dfg_FPrintDescription(FILE*);
+
+void        dfg_DeleteProofList(LIST);
+
+CLAUSE      dfg_CreateClauseFromTerm(TERM, BOOL, FLAGSTORE, PRECEDENCE); 
+TERM        dfg_CreateQuantifier(SYMBOL, LIST, TERM);
+
+#endif
diff --git a/test/spass/dfgparser.c b/test/spass/dfgparser.c
new file mode 100644
index 0000000000000000000000000000000000000000..3691271b53b6548d9cb773130c6dadaf2ea40cf0
--- /dev/null
+++ b/test/spass/dfgparser.c
@@ -0,0 +1,3728 @@
+/* A Bison parser, made from dfgparser.y, by GNU bison 1.75.  */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 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, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Written by Richard Stallman by simplifying the original so called
+   ``semantic'' parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON	1
+
+/* Pure parsers.  */
+#define YYPURE	0
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+/* If NAME_PREFIX is specified substitute the variables and functions
+   names.  */
+#define yyparse dfg_parse
+#define yylex   dfg_lex
+#define yyerror dfg_error
+#define yylval  dfg_lval
+#define yychar  dfg_char
+#define yydebug dfg_debug
+#define yynerrs dfg_nerrs
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     DFG_AND = 258,
+     DFG_AUTHOR = 259,
+     DFG_AXIOMS = 260,
+     DFG_BEGPROB = 261,
+     DFG_BY = 262,
+     DFG_CLAUSE = 263,
+     DFG_CLOSEBRACE = 264,
+     DFG_CLSLIST = 265,
+     DFG_CNF = 266,
+     DFG_CONJECS = 267,
+     DFG_DATE = 268,
+     DFG_DECLLIST = 269,
+     DFG_DESC = 270,
+     DFG_DESCLIST = 271,
+     DFG_DNF = 272,
+     DFG_DOMPRED = 273,
+     DFG_ENDLIST = 274,
+     DFG_ENDPROB = 275,
+     DFG_EQUAL = 276,
+     DFG_EQUIV = 277,
+     DFG_EXISTS = 278,
+     DFG_FALSE = 279,
+     DFG_FORMLIST = 280,
+     DFG_FORMULA = 281,
+     DFG_FORALL = 282,
+     DFG_FREELY = 283,
+     DFG_FUNC = 284,
+     DFG_GENERATED = 285,
+     DFG_GENSET = 286,
+     DFG_HYPOTH = 287,
+     DFG_IMPLIED = 288,
+     DFG_IMPLIES = 289,
+     DFG_LOGIC = 290,
+     DFG_NAME = 291,
+     DFG_NOT = 292,
+     DFG_OPENBRACE = 293,
+     DFG_OPERAT = 294,
+     DFG_OR = 295,
+     DFG_PREC = 296,
+     DFG_PRED = 297,
+     DFG_PRDICAT = 298,
+     DFG_PRFLIST = 299,
+     DFG_QUANTIF = 300,
+     DFG_SATIS = 301,
+     DFG_SETFLAG = 302,
+     DFG_SETTINGS = 303,
+     DFG_SYMLIST = 304,
+     DFG_SORT = 305,
+     DFG_SORTS = 306,
+     DFG_STATUS = 307,
+     DFG_STEP = 308,
+     DFG_SUBSORT = 309,
+     DFG_TERMLIST = 310,
+     DFG_TRUE = 311,
+     DFG_UNKNOWN = 312,
+     DFG_UNSATIS = 313,
+     DFG_VERSION = 314,
+     DFG_NUM = 315,
+     DFG_MINUS1 = 316,
+     DFG_ID = 317,
+     DFG_TEXT = 318
+   };
+#endif
+#define DFG_AND 258
+#define DFG_AUTHOR 259
+#define DFG_AXIOMS 260
+#define DFG_BEGPROB 261
+#define DFG_BY 262
+#define DFG_CLAUSE 263
+#define DFG_CLOSEBRACE 264
+#define DFG_CLSLIST 265
+#define DFG_CNF 266
+#define DFG_CONJECS 267
+#define DFG_DATE 268
+#define DFG_DECLLIST 269
+#define DFG_DESC 270
+#define DFG_DESCLIST 271
+#define DFG_DNF 272
+#define DFG_DOMPRED 273
+#define DFG_ENDLIST 274
+#define DFG_ENDPROB 275
+#define DFG_EQUAL 276
+#define DFG_EQUIV 277
+#define DFG_EXISTS 278
+#define DFG_FALSE 279
+#define DFG_FORMLIST 280
+#define DFG_FORMULA 281
+#define DFG_FORALL 282
+#define DFG_FREELY 283
+#define DFG_FUNC 284
+#define DFG_GENERATED 285
+#define DFG_GENSET 286
+#define DFG_HYPOTH 287
+#define DFG_IMPLIED 288
+#define DFG_IMPLIES 289
+#define DFG_LOGIC 290
+#define DFG_NAME 291
+#define DFG_NOT 292
+#define DFG_OPENBRACE 293
+#define DFG_OPERAT 294
+#define DFG_OR 295
+#define DFG_PREC 296
+#define DFG_PRED 297
+#define DFG_PRDICAT 298
+#define DFG_PRFLIST 299
+#define DFG_QUANTIF 300
+#define DFG_SATIS 301
+#define DFG_SETFLAG 302
+#define DFG_SETTINGS 303
+#define DFG_SYMLIST 304
+#define DFG_SORT 305
+#define DFG_SORTS 306
+#define DFG_STATUS 307
+#define DFG_STEP 308
+#define DFG_SUBSORT 309
+#define DFG_TERMLIST 310
+#define DFG_TRUE 311
+#define DFG_UNKNOWN 312
+#define DFG_UNSATIS 313
+#define DFG_VERSION 314
+#define DFG_NUM 315
+#define DFG_MINUS1 316
+#define DFG_ID 317
+#define DFG_TEXT 318
+
+
+
+
+/* Copy the first part of user declarations.  */
+#line 48 "dfgparser.y"
+
+
+#include <ctype.h>
+#include "dfg.h"
+#include "symbol.h"
+#include "term.h"
+#include "foldfg.h"
+#include "stringsx.h"
+
+/* Used for the texts from description section. */
+typedef struct {
+  char*     name;
+  char*     author;
+  char*     version;
+  char*     logic;
+  DFG_STATE status;
+  char*     description;
+  char*     date;
+} DFG_DESCRIPTIONTYPE;
+
+static DFG_DESCRIPTIONTYPE dfg_DESC;
+static LIST                dfg_AXIOMLIST;
+static LIST                dfg_CONJECLIST;
+static LIST                dfg_SORTDECLLIST;
+/* symbol precedence explicitly defined by user */
+static LIST                dfg_USERPRECEDENCE;
+static LIST                dfg_AXCLAUSES;
+static LIST                dfg_CONCLAUSES;
+static LIST                dfg_PROOFLIST;     /* list_of_proofs */
+static LIST                dfg_TERMLIST;      /* list_of_terms  */
+static BOOL                dfg_IGNORE;      /* tokens are ignored while TRUE */
+static FLAGSTORE           dfg_FLAGS;
+static PRECEDENCE          dfg_PRECEDENCE;
+
+/* used also in the scanner */
+NAT                        dfg_LINENUMBER;
+BOOL			   dfg_IGNORETEXT;
+
+void yyerror(const char*);
+int  yylex(void);		/* Defined in dfgscanner.l */
+
+static void   dfg_SymbolDecl(int, char*, int);
+static SYMBOL dfg_Symbol(char*, NAT);
+static void   dfg_SubSort(char*, char*);
+static void   dfg_SymbolGenerated(SYMBOL, BOOL, LIST);
+
+static __inline__ TERM dfg_TermCreate(char* Name, LIST Arguments)
+/* Look up the symbol, check its arity and create the term */
+{
+  SYMBOL s;
+  NAT    arity;
+  arity = list_Length(Arguments);
+  s = dfg_Symbol(Name, arity); /* Frees the string */
+  if (!symbol_IsVariable(s) && !symbol_IsFunction(s)) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n Line %d: is not a function.\n", dfg_LINENUMBER);
+    misc_FinishUserErrorReport();
+  }
+  return term_Create(s, Arguments);
+}
+
+static __inline__ TERM dfg_AtomCreate(char* Name, LIST Arguments)
+/* Look up the symbol, check its arity and create the atom term */
+{
+  SYMBOL s;
+  s = dfg_Symbol(Name, list_Length(Arguments)); /* Frees the string */
+  if (symbol_IsVariable(s) || !symbol_IsPredicate(s)) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n Line %d: Symbol is not a predicate.\n", dfg_LINENUMBER);
+    misc_FinishUserErrorReport();
+  }
+  return term_Create(s, Arguments);
+}
+
+static __inline__ void dfg_DeleteStringList(LIST List)
+{
+  list_DeleteWithElement(List, (void (*)(POINTER)) string_StringFree);
+}
+
+/**************************************************************/
+/* Functions that handle symbols with unspecified arity       */
+/**************************************************************/
+
+/* The symbol list holds all symbols whose arity wasn't       */
+/* specified in the symbol declaration section.               */
+/* If the arity of a symbol was not specified in this section */
+/* it is first set to 0. If the symbol occurs with always the */
+/* same arity 'A' the arity of this symbol is set to 'A'.     */
+static LIST   dfg_SYMBOLLIST;
+
+static void dfg_SymAdd(SYMBOL);
+static void dfg_SymCheck(SYMBOL, NAT);
+static void dfg_SymCleanUp(void);
+
+/**************************************************************/
+/* Functions that handle variable names                       */
+/**************************************************************/
+
+/* List of quantified variables in the current input formula. */
+/* This list is used to find symbols that by mistake weren't  */
+/* declared in the symbol declaration section                 */
+/* --> free variables                                         */
+/* This is a list of lists, since each time a quantifier is   */
+/* reached, a new list is added to the global list.           */
+static LIST dfg_VARLIST;
+static BOOL dfg_VARDECL;
+
+static void   dfg_VarStart(void);
+static void   dfg_VarStop(void);
+static void   dfg_VarBacktrack(void);
+static void   dfg_VarCheck(void);
+static SYMBOL dfg_VarLookup(char*);
+
+#define YYERROR_VERBOSE
+
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+#ifndef YYSTYPE
+#line 165 "dfgparser.y"
+typedef union {
+  int       number;
+  char*     string;
+  SYMBOL    symbol;
+  SPROPERTY property;
+  TERM      term;
+  LIST      list;
+  DFG_STATE state;
+  BOOL      bool;
+} yystype;
+/* Line 193 of /opt/gnu//share/bison/yacc.c.  */
+#line 336 "dfgparser.c"
+# define YYSTYPE yystype
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+#ifndef YYLTYPE
+typedef struct yyltype
+{
+  int first_line;
+  int first_column;
+  int last_line;
+  int last_column;
+} yyltype;
+# define YYLTYPE yyltype
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 213 of /opt/gnu//share/bison/yacc.c.  */
+#line 357 "dfgparser.c"
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# if YYSTACK_USE_ALLOCA
+#  define YYSTACK_ALLOC alloca
+# else
+#  ifndef YYSTACK_USE_ALLOCA
+#   if defined (alloca) || defined (_ALLOCA_H)
+#    define YYSTACK_ALLOC alloca
+#   else
+#    ifdef __GNUC__
+#     define YYSTACK_ALLOC __builtin_alloca
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning. */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+#  if defined (__STDC__) || defined (__cplusplus)
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   define YYSIZE_T size_t
+#  endif
+#  define YYSTACK_ALLOC malloc
+#  define YYSTACK_FREE free
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+     && (! defined (__cplusplus) \
+	 || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  short yyss;
+  YYSTYPE yyvs;
+  };
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (short) + sizeof (YYSTYPE))				\
+      + YYSTACK_GAP_MAX)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  register YYSIZE_T yyi;		\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];	\
+	}					\
+      while (0)
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)					\
+    do									\
+      {									\
+	YYSIZE_T yynewbytes;						\
+	YYCOPY (&yyptr->Stack, Stack, yysize);				\
+	Stack = &yyptr->Stack;						\
+	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX;	\
+	yyptr += yynewbytes / sizeof (*yyptr);				\
+      }									\
+    while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+   typedef signed char yysigned_char;
+#else
+   typedef short yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL  4
+#define YYLAST   506
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS  71
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS  100
+/* YYNRULES -- Number of rules. */
+#define YYNRULES  196
+/* YYNRULES -- Number of states. */
+#define YYNSTATES  477
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   318
+
+#define YYTRANSLATE(X) \
+  ((unsigned)(X) <= YYMAXUTOK ? yytranslate[X] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const unsigned char yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+      64,    65,     2,     2,    69,     2,    66,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,    70,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,    67,     2,    68,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
+      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
+      55,    56,    57,    58,    59,    60,    61,    62,    63
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const unsigned short yyprhs[] =
+{
+       0,     0,     3,    14,    26,    32,    38,    44,    50,    51,
+      57,    58,    64,    65,    71,    73,    75,    77,    84,    85,
+      95,    96,   102,   104,   108,   110,   116,   117,   123,   125,
+     129,   131,   137,   138,   144,   146,   150,   151,   157,   159,
+     163,   165,   171,   172,   178,   180,   184,   186,   192,   194,
+     196,   197,   203,   204,   207,   209,   217,   220,   228,   229,
+     230,   242,   252,   253,   255,   257,   261,   263,   267,   276,
+     278,   280,   281,   284,   285,   293,   294,   297,   299,   304,
+     311,   316,   317,   318,   329,   330,   332,   334,   338,   340,
+     342,   344,   346,   348,   350,   352,   354,   356,   358,   360,
+     362,   364,   368,   370,   375,   376,   379,   390,   391,   403,
+     404,   412,   413,   415,   417,   418,   419,   430,   435,   437,
+     441,   443,   448,   450,   454,   456,   458,   460,   467,   472,
+     473,   481,   482,   484,   486,   495,   500,   502,   507,   509,
+     513,   514,   517,   518,   528,   529,   545,   547,   551,   552,
+     557,   561,   567,   568,   572,   574,   576,   578,   580,   582,
+     584,   586,   588,   590,   591,   595,   603,   605,   607,   608,
+     611,   612,   619,   620,   624,   625,   628,   634,   635,   645,
+     647,   651,   652,   656,   661,   666,   673,   675,   679,   681,
+     688,   689,   692,   694,   697,   703,   705
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const short yyrhs[] =
+{
+      72,     0,    -1,     6,    64,   121,    65,    66,    73,    82,
+     159,    20,    66,    -1,    16,    66,    74,    75,    78,    79,
+      76,    77,    80,    19,    66,    -1,    36,    64,    63,    65,
+      66,    -1,     4,    64,    63,    65,    66,    -1,    52,    64,
+      81,    65,    66,    -1,    15,    64,    63,    65,    66,    -1,
+      -1,    59,    64,    63,    65,    66,    -1,    -1,    35,    64,
+      63,    65,    66,    -1,    -1,    13,    64,    63,    65,    66,
+      -1,    46,    -1,    58,    -1,    57,    -1,    83,    99,   110,
+     124,   143,   155,    -1,    -1,    49,    66,    84,    87,    90,
+      92,    95,    19,    66,    -1,    -1,    29,    67,    85,    68,
+      66,    -1,    86,    -1,    85,    69,    86,    -1,   121,    -1,
+      64,   121,    69,    98,    65,    -1,    -1,    43,    67,    88,
+      68,    66,    -1,    89,    -1,    88,    69,    89,    -1,   121,
+      -1,    64,   121,    69,    98,    65,    -1,    -1,    51,    67,
+      91,    68,    66,    -1,   121,    -1,    91,    69,   121,    -1,
+      -1,    39,    67,    93,    68,    66,    -1,    94,    -1,    93,
+      69,    94,    -1,   121,    -1,    64,   121,    69,    98,    65,
+      -1,    -1,    45,    67,    96,    68,    66,    -1,    97,    -1,
+      96,    69,    97,    -1,   121,    -1,    64,   121,    69,    98,
+      65,    -1,    61,    -1,    60,    -1,    -1,    14,    66,   100,
+      19,    66,    -1,    -1,   100,   101,    -1,   104,    -1,    54,
+      64,   121,    69,   121,    65,    66,    -1,   136,    66,    -1,
+      42,    64,   121,    69,   107,    65,    66,    -1,    -1,    -1,
+      27,    64,    67,   102,   122,   103,    68,    69,   136,    65,
+      66,    -1,    50,   121,   105,    30,     7,    67,   106,    68,
+      66,    -1,    -1,    28,    -1,   121,    -1,   106,    69,   121,
+      -1,   121,    -1,   107,    69,   121,    -1,    25,    64,   109,
+      65,    66,   111,    19,    66,    -1,     5,    -1,    12,    -1,
+      -1,   110,   108,    -1,    -1,   111,    26,    64,   116,   112,
+      65,    66,    -1,    -1,    69,   121,    -1,   136,    -1,    37,
+      64,   113,    65,    -1,   118,    64,   113,    69,   113,    65,
+      -1,   119,    64,   117,    65,    -1,    -1,    -1,   120,    64,
+      67,   114,   122,   115,    68,    69,   113,    65,    -1,    -1,
+     113,    -1,   113,    -1,   117,    69,   113,    -1,    22,    -1,
+      33,    -1,    34,    -1,     3,    -1,    40,    -1,    23,    -1,
+      27,    -1,    62,    -1,    60,    -1,    47,    -1,    18,    -1,
+      41,    -1,   123,    -1,   122,    69,   123,    -1,   121,    -1,
+     121,    64,   121,    65,    -1,    -1,   124,   125,    -1,    10,
+      64,   109,    69,    11,    65,    66,   127,    19,    66,    -1,
+      -1,    10,    64,   109,    69,    17,    65,    66,   126,   137,
+      19,    66,    -1,    -1,   127,     8,    64,   128,   112,    65,
+      66,    -1,    -1,   129,    -1,   132,    -1,    -1,    -1,    27,
+      64,    67,   130,   122,   131,    68,    69,   132,    65,    -1,
+      40,    64,   133,    65,    -1,   134,    -1,   133,    69,   134,
+      -1,   136,    -1,    37,    64,   136,    65,    -1,   136,    -1,
+     135,    69,   136,    -1,   121,    -1,    56,    -1,    24,    -1,
+      21,    64,   141,    69,   141,    65,    -1,   121,    64,   142,
+      65,    -1,    -1,   137,     8,    64,   138,   112,    65,    66,
+      -1,    -1,   139,    -1,   140,    -1,    23,    64,    67,   135,
+      68,    69,   140,    65,    -1,     3,    64,   133,    65,    -1,
+     121,    -1,   121,    64,   142,    65,    -1,   141,    -1,   142,
+      69,   141,    -1,    -1,   143,   144,    -1,    -1,    44,    64,
+     121,    65,    66,   145,   146,    19,    66,    -1,    -1,   146,
+      53,    64,   150,    69,   154,    69,   121,    69,    67,   147,
+      68,   148,    65,    66,    -1,   150,    -1,   147,    69,   150,
+      -1,    -1,    69,    67,   149,    68,    -1,   150,    70,   150,
+      -1,   149,    69,   150,    70,   150,    -1,    -1,   152,   151,
+     153,    -1,   121,    -1,    37,    -1,    22,    -1,    33,    -1,
+      34,    -1,     3,    -1,    40,    -1,    27,    -1,    23,    -1,
+      -1,    64,   117,    65,    -1,    64,    67,   122,    68,    69,
+     113,    65,    -1,   129,    -1,   139,    -1,    -1,   155,   156,
+      -1,    -1,    55,    66,   157,   158,    19,    66,    -1,    -1,
+     158,   141,    66,    -1,    -1,   159,   160,    -1,    31,    66,
+     168,    19,    66,    -1,    -1,    48,    64,   121,   161,    65,
+      66,   162,    19,    66,    -1,    63,    -1,    38,   163,     9,
+      -1,    -1,   163,   164,    66,    -1,    41,    64,   165,    65,
+      -1,    18,    64,   170,    65,    -1,    47,    64,    62,    69,
+      98,    65,    -1,   166,    -1,   165,    69,   166,    -1,   121,
+      -1,    64,   121,    69,    60,   167,    65,    -1,    -1,    69,
+      62,    -1,   169,    -1,   168,   169,    -1,    32,    67,   170,
+      68,    66,    -1,   121,    -1,   170,    69,   121,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const unsigned short yyrline[] =
+{
+       0,   206,   206,   218,   229,   233,   237,   241,   245,   246,
+     250,   251,   255,   256,   260,   261,   262,   269,   281,   282,
+     291,   292,   295,   296,   299,   300,   304,   305,   308,   309,
+     312,   313,   316,   317,   320,   321,   324,   325,   328,   329,
+     332,   333,   336,   337,   340,   341,   344,   345,   348,   349,
+     356,   357,   362,   363,   366,   367,   369,   370,   372,   373,
+     372,   382,   386,   387,   390,   391,   394,   395,   402,   412,
+     413,   416,   417,   420,   421,   435,   436,   439,   440,   442,
+     444,   446,   447,   446,   454,   455,   458,   460,   464,   465,
+     466,   469,   470,   473,   474,   477,   483,   485,   487,   489,
+     493,   495,   499,   510,   534,   535,   538,   548,   547,   554,
+     555,   569,   570,   573,   574,   575,   574,   582,   586,   588,
+     592,   593,   597,   598,   601,   603,   605,   607,   609,   616,
+     617,   620,   621,   624,   625,   628,   635,   637,   641,   643,
+     651,   652,   656,   655,   669,   670,   691,   693,   698,   699,
+     702,   710,   721,   720,   732,   733,   734,   735,   736,   737,
+     738,   739,   740,   743,   744,   745,   748,   749,   757,   758,
+     761,   761,   768,   769,   776,   777,   780,   781,   781,   789,
+     792,   795,   796,   799,   800,   820,   832,   833,   836,   848,
+     865,   866,   883,   884,   887,   891,   892
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE
+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "DFG_AND", "DFG_AUTHOR", "DFG_AXIOMS", 
+  "DFG_BEGPROB", "DFG_BY", "DFG_CLAUSE", "DFG_CLOSEBRACE", "DFG_CLSLIST", 
+  "DFG_CNF", "DFG_CONJECS", "DFG_DATE", "DFG_DECLLIST", "DFG_DESC", 
+  "DFG_DESCLIST", "DFG_DNF", "DFG_DOMPRED", "DFG_ENDLIST", "DFG_ENDPROB", 
+  "DFG_EQUAL", "DFG_EQUIV", "DFG_EXISTS", "DFG_FALSE", "DFG_FORMLIST", 
+  "DFG_FORMULA", "DFG_FORALL", "DFG_FREELY", "DFG_FUNC", "DFG_GENERATED", 
+  "DFG_GENSET", "DFG_HYPOTH", "DFG_IMPLIED", "DFG_IMPLIES", "DFG_LOGIC", 
+  "DFG_NAME", "DFG_NOT", "DFG_OPENBRACE", "DFG_OPERAT", "DFG_OR", 
+  "DFG_PREC", "DFG_PRED", "DFG_PRDICAT", "DFG_PRFLIST", "DFG_QUANTIF", 
+  "DFG_SATIS", "DFG_SETFLAG", "DFG_SETTINGS", "DFG_SYMLIST", "DFG_SORT", 
+  "DFG_SORTS", "DFG_STATUS", "DFG_STEP", "DFG_SUBSORT", "DFG_TERMLIST", 
+  "DFG_TRUE", "DFG_UNKNOWN", "DFG_UNSATIS", "DFG_VERSION", "DFG_NUM", 
+  "DFG_MINUS1", "DFG_ID", "DFG_TEXT", "'('", "')'", "'.'", "'['", "']'", 
+  "','", "':'", "$accept", "problem", "description", "name", "author", 
+  "status", "desctext", "versionopt", "logicopt", "dateopt", "log_state", 
+  "logicalpart", "symbollistopt", "functionsopt", "functionlist", "func", 
+  "predicatesopt", "predicatelist", "pred", "sortsopt", "sortlist", 
+  "operatorsopt", "operatorlist", "op", "quantifiersopt", 
+  "quantifierlist", "quant", "number", "declarationlistopt", 
+  "decllistopt", "decl", "@1", "@2", "gendecl", "freelyopt", "funclist", 
+  "sortdecl", "formulalist", "origin", "formulalistsopt", 
+  "formulalistopt", "labelopt", "formula", "@3", "@4", "formulaopt", 
+  "arglist", "binsymbol", "nsymbol", "quantsymbol", "id", "qtermlist", 
+  "qterm", "clauselistsopt", "clauselist", "@5", "cnfclausesopt", 
+  "cnfclauseopt", "cnfclause", "@6", "@7", "cnfclausebody", "litlist", 
+  "lit", "atomlist", "atom", "dnfclausesopt", "dnfclauseopt", "dnfclause", 
+  "dnfclausebody", "term", "termlist", "prooflistsopt", "prooflist", "@8", 
+  "prooflistopt", "parentlist", "assoclistopt", "assoclist", 
+  "id_or_formula", "@9", "anysymbol", "optargs", "clause", 
+  "listOfTermsopt", "listOfTerms", "@10", "terms", "settinglistsopt", 
+  "settinglist", "@11", "flags", "spassflags", "spassflag", "preclist", 
+  "precitem", "statopt", "gsettings", "gsetting", "labellist", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const unsigned short yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
+     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
+     295,   296,   297,   298,   299,   300,   301,   302,   303,   304,
+     305,   306,   307,   308,   309,   310,   311,   312,   313,   314,
+     315,   316,   317,   318,    40,    41,    46,    91,    93,    44,
+      58
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const unsigned char yyr1[] =
+{
+       0,    71,    72,    73,    74,    75,    76,    77,    78,    78,
+      79,    79,    80,    80,    81,    81,    81,    82,    83,    83,
+      84,    84,    85,    85,    86,    86,    87,    87,    88,    88,
+      89,    89,    90,    90,    91,    91,    92,    92,    93,    93,
+      94,    94,    95,    95,    96,    96,    97,    97,    98,    98,
+      99,    99,   100,   100,   101,   101,   101,   101,   102,   103,
+     101,   104,   105,   105,   106,   106,   107,   107,   108,   109,
+     109,   110,   110,   111,   111,   112,   112,   113,   113,   113,
+     113,   114,   115,   113,   116,   116,   117,   117,   118,   118,
+     118,   119,   119,   120,   120,   121,   121,   121,   121,   121,
+     122,   122,   123,   123,   124,   124,   125,   126,   125,   127,
+     127,   128,   128,   129,   130,   131,   129,   132,   133,   133,
+     134,   134,   135,   135,   136,   136,   136,   136,   136,   137,
+     137,   138,   138,   139,   139,   140,   141,   141,   142,   142,
+     143,   143,   145,   144,   146,   146,   147,   147,   148,   148,
+     149,   149,   151,   150,   152,   152,   152,   152,   152,   152,
+     152,   152,   152,   153,   153,   153,   154,   154,   155,   155,
+     157,   156,   158,   158,   159,   159,   160,   161,   160,   162,
+     162,   163,   163,   164,   164,   164,   165,   165,   166,   166,
+     167,   167,   168,   168,   169,   170,   170
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const unsigned char yyr2[] =
+{
+       0,     2,    10,    11,     5,     5,     5,     5,     0,     5,
+       0,     5,     0,     5,     1,     1,     1,     6,     0,     9,
+       0,     5,     1,     3,     1,     5,     0,     5,     1,     3,
+       1,     5,     0,     5,     1,     3,     0,     5,     1,     3,
+       1,     5,     0,     5,     1,     3,     1,     5,     1,     1,
+       0,     5,     0,     2,     1,     7,     2,     7,     0,     0,
+      11,     9,     0,     1,     1,     3,     1,     3,     8,     1,
+       1,     0,     2,     0,     7,     0,     2,     1,     4,     6,
+       4,     0,     0,    10,     0,     1,     1,     3,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     3,     1,     4,     0,     2,    10,     0,    11,     0,
+       7,     0,     1,     1,     0,     0,    10,     4,     1,     3,
+       1,     4,     1,     3,     1,     1,     1,     6,     4,     0,
+       7,     0,     1,     1,     8,     4,     1,     4,     1,     3,
+       0,     2,     0,     9,     0,    15,     1,     3,     0,     4,
+       3,     5,     0,     3,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     0,     3,     7,     1,     1,     0,     2,
+       0,     6,     0,     3,     0,     2,     5,     0,     9,     1,
+       3,     0,     3,     4,     4,     6,     1,     3,     1,     6,
+       0,     2,     1,     2,     5,     1,     3
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const unsigned char yydefact[] =
+{
+       0,     0,     0,     0,     1,    98,    99,    97,    96,    95,
+       0,     0,     0,     0,    18,     0,     0,   174,    50,     0,
+       0,    20,     0,     0,    71,     0,     0,     8,     0,    26,
+       0,     0,     0,   175,    52,   104,     0,     0,     0,    10,
+       0,     0,    32,     2,     0,     0,     0,     0,    72,   140,
+       0,     0,     0,     0,     0,     0,     0,    22,    24,     0,
+       0,    36,     0,     0,   192,   177,     0,     0,   126,     0,
+       0,     0,     0,   125,    53,    54,   124,     0,     0,     0,
+     105,   168,     4,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,    28,    30,     0,     0,    42,     0,     0,
+     193,     0,    51,     0,     0,     0,    62,     0,     0,    56,
+      69,    70,     0,     0,     0,   141,    17,     5,     0,     0,
+       0,     0,    12,     0,    21,    23,     0,     0,     0,     0,
+      34,     0,     0,     0,   195,     0,   176,     0,   136,     0,
+      58,     0,    63,     0,     0,   138,     0,     0,     0,     0,
+       0,   169,     9,     0,    14,    16,    15,     0,     0,     0,
+       0,    49,    48,     0,     0,    27,    29,     0,     0,     0,
+       0,    38,    40,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   128,     0,    73,     0,     0,   170,
+      11,     0,     0,     0,     0,    25,     0,    33,    35,     0,
+       0,     0,     0,     0,    44,    46,    19,   194,   196,   181,
+     179,     0,     0,     0,   102,    59,   100,     0,    66,     0,
+       0,   139,     0,     0,     0,     0,   172,     6,     0,     0,
+       3,    31,     0,    37,    39,     0,     0,     0,     0,     0,
+     137,   127,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,   142,     0,     7,     0,     0,     0,    43,
+      45,   180,     0,     0,     0,     0,   178,     0,   101,     0,
+      57,    67,     0,    64,    55,    68,    84,   109,   107,   144,
+       0,     0,    13,    41,     0,     0,     0,     0,   182,   103,
+       0,     0,     0,    91,    88,    93,    94,    89,    90,     0,
+      92,    85,    75,     0,     0,     0,    77,     0,   129,     0,
+     171,   173,    47,     0,     0,   188,     0,   186,     0,     0,
+      61,    65,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,   184,     0,   183,     0,     0,     0,     0,
+      76,     0,     0,    86,     0,    81,   111,   106,     0,     0,
+     143,     0,     0,   187,     0,    60,    78,    74,     0,    80,
+       0,     0,     0,     0,    75,   112,   113,   131,   108,   159,
+     156,   162,   161,   157,   158,   155,   160,   154,     0,   152,
+     190,   185,     0,    87,    82,     0,     0,     0,     0,     0,
+      75,   132,   133,     0,   163,     0,     0,    79,     0,   114,
+       0,     0,   118,   120,     0,     0,     0,     0,   166,   167,
+       0,     0,   153,   191,   189,     0,     0,     0,   117,     0,
+     110,     0,     0,     0,     0,     0,     0,     0,   115,     0,
+     119,   135,     0,   122,   130,     0,     0,   164,     0,     0,
+     121,     0,     0,     0,     0,    83,     0,     0,   123,     0,
+       0,     0,     0,     0,   146,     0,     0,   134,   148,     0,
+     165,   116,     0,     0,   147,     0,     0,     0,     0,   145,
+     149,     0,     0,     0,   150,     0,   151
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const short yydefgoto[] =
+{
+      -1,     2,    14,    20,    27,    87,   122,    39,    54,   160,
+     157,    17,    18,    29,    56,    57,    42,    92,    93,    61,
+     129,    97,   170,   171,   133,   203,   204,   163,    24,    46,
+      74,   180,   244,    75,   143,   272,   217,    48,   112,    35,
+     222,   324,   343,   361,   398,   302,   344,   303,   304,   305,
+      76,   215,   216,    49,    80,   308,   307,   364,   365,   416,
+     439,   366,   401,   402,   432,   306,   330,   390,   391,   392,
+     145,   146,    81,   115,   279,   309,   453,   463,   467,   378,
+     394,   379,   412,   410,   116,   151,   226,   254,    22,    33,
+     101,   211,   238,   265,   316,   317,   396,    63,    64,   135
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -356
+static const short yypact[] =
+{
+       9,   -32,    35,   232,  -356,  -356,  -356,  -356,  -356,  -356,
+      -6,    13,    67,    20,    45,    53,    30,  -356,   110,    46,
+     118,   121,   -12,    73,  -356,    91,    84,   113,   112,   141,
+     123,   128,   132,  -356,  -356,   175,   152,   161,   155,   191,
+       2,   162,   180,  -356,   204,   232,   214,   173,  -356,   252,
+     176,   206,   209,   213,   226,   232,    47,  -356,  -356,    80,
+     218,   254,   224,   -14,  -356,  -356,   230,   233,  -356,   234,
+     241,   232,   242,  -356,  -356,  -356,   243,   237,    21,   244,
+    -356,   260,  -356,   246,   245,   250,   251,   294,   247,   248,
+       2,   232,    93,  -356,  -356,   232,   255,   272,   232,   253,
+    -356,   256,  -356,   232,   257,   232,   290,   232,   232,  -356,
+    -356,  -356,   258,    21,   261,  -356,   271,  -356,   262,   264,
+      14,   263,   317,   108,  -356,  -356,   265,   266,    80,   119,
+    -356,    85,   268,   312,  -356,   124,  -356,   270,   273,   269,
+    -356,   274,  -356,   309,   275,  -356,   -52,   276,   277,   232,
+     279,  -356,  -356,   281,  -356,  -356,  -356,   284,   287,   288,
+     321,  -356,  -356,   286,   108,  -356,  -356,   289,   232,   232,
+     138,  -356,  -356,   156,   291,   293,   232,   -17,   232,   232,
+     232,   232,   346,   232,  -356,   232,  -356,    40,   296,  -356,
+    -356,   297,   299,   302,   300,  -356,   303,  -356,  -356,   285,
+     301,    85,   232,   143,  -356,  -356,  -356,  -356,  -356,  -356,
+    -356,   337,    16,   304,   298,   306,  -356,    32,  -356,   311,
+     305,  -356,    56,   308,   314,   310,  -356,  -356,   315,   318,
+    -356,  -356,   108,  -356,  -356,   313,   319,   156,    -2,   320,
+    -356,  -356,   232,   232,   316,   322,   232,   232,   323,   324,
+     307,   325,   326,  -356,   240,  -356,   327,   329,   108,  -356,
+    -356,  -356,   331,   332,   334,   333,  -356,   335,  -356,   336,
+    -356,  -356,   145,  -356,  -356,  -356,    96,  -356,  -356,  -356,
+     338,   340,  -356,  -356,   342,   232,   163,   339,  -356,  -356,
+     239,   343,   232,  -356,  -356,  -356,  -356,  -356,  -356,   344,
+    -356,  -356,   341,   347,   348,   350,  -356,     3,  -356,   -15,
+    -356,  -356,  -356,    42,   232,  -356,    43,  -356,   349,   351,
+    -356,  -356,    96,   232,   352,    96,    96,   353,   355,   357,
+      57,   358,   361,  -356,   359,  -356,   163,   108,   360,   362,
+    -356,   363,   364,  -356,    44,  -356,   -13,  -356,   366,   365,
+    -356,   168,   372,  -356,   369,  -356,  -356,  -356,    96,  -356,
+      96,   232,   371,   373,   341,  -356,  -356,     0,  -356,  -356,
+    -356,  -356,  -356,  -356,  -356,  -356,  -356,  -356,   367,  -356,
+     370,  -356,   375,  -356,   306,   374,   228,   377,   379,   380,
+     341,  -356,  -356,    50,   381,   376,   382,  -356,   383,  -356,
+     384,    66,  -356,  -356,   386,   228,   387,   385,  -356,  -356,
+     388,     7,  -356,  -356,  -356,   389,   232,   239,  -356,   228,
+    -356,    69,   239,   393,   232,   232,    90,    96,   306,   390,
+    -356,  -356,   153,  -356,  -356,   391,   179,  -356,   396,   395,
+    -356,   397,   239,   398,   401,  -356,   402,   399,  -356,   168,
+      96,   409,   408,   185,  -356,   410,   411,  -356,   405,   168,
+    -356,  -356,   400,   412,  -356,   168,   413,   198,   345,  -356,
+    -356,   168,   168,   394,  -356,   168,  -356
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const short yypgoto[] =
+{
+    -356,  -356,  -356,  -356,  -356,  -356,  -356,  -356,  -356,  -356,
+    -356,  -356,  -356,  -356,  -356,   392,  -356,  -356,   259,  -356,
+    -356,  -356,  -356,   202,  -356,  -356,   216,  -152,  -356,  -356,
+    -356,  -356,  -356,  -356,  -356,  -356,  -356,  -356,   267,  -356,
+    -356,  -340,  -267,  -356,  -356,  -356,    70,  -356,  -356,  -356,
+      -3,  -355,   235,  -356,  -356,  -356,  -356,  -356,    87,  -356,
+    -356,    33,    78,    68,  -356,   -45,  -356,  -356,    92,    39,
+    -101,   328,  -356,  -356,  -356,  -356,  -356,  -356,  -356,  -308,
+    -356,  -356,  -356,  -356,  -356,  -356,  -356,  -356,  -356,  -356,
+    -356,  -356,  -356,  -356,  -356,   154,  -356,  -356,   425,   207
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, parse error.  */
+#define YYTABLE_NINF -1
+static const unsigned short yytable[] =
+{
+      10,    77,   139,   388,   331,    99,   384,   261,    30,   301,
+     293,   328,   196,   184,   362,     1,   262,   185,    62,    31,
+       5,   209,   329,   389,   387,     5,   110,   363,    67,   294,
+     295,    68,     3,   111,   296,     4,    32,    58,   332,   263,
+     297,   298,    65,     6,   299,   264,   210,   300,     6,     7,
+     407,   223,    88,   388,     7,   339,    94,   224,   342,    11,
+     154,   428,     8,    73,     9,   348,    55,     8,   106,     9,
+     436,   155,   156,   389,   425,   249,   349,   362,   213,    12,
+     257,   240,   250,    13,   221,   185,    15,    58,   126,    19,
+     363,   382,   130,   383,    16,   134,    21,   245,     5,   293,
+     138,   246,   141,     5,   144,   138,   284,   333,   335,   359,
+      25,   176,   336,   360,     5,    89,    90,    67,   294,   295,
+      68,     6,    26,   296,    23,    94,     6,     7,   172,   297,
+     298,   418,     7,   299,   431,   419,   300,     6,   419,    34,
+       8,   454,     9,     7,    91,     8,   188,     9,    37,   169,
+      28,   464,    73,   281,    36,   437,     8,   468,     9,   360,
+     438,   127,   128,   473,   474,   198,   199,   476,   161,   162,
+     205,   369,    38,   208,     5,   138,   138,   214,   218,    40,
+     220,     5,   138,   455,    41,   354,     5,   167,   168,    43,
+     370,   371,   175,   176,    44,   372,    45,     6,   172,   235,
+      47,   373,   374,     7,     6,   375,   200,   201,   376,     6,
+       7,   236,   237,   291,   292,     7,     8,    50,     9,    52,
+     202,   441,   442,     8,    51,     9,    53,   314,     8,    59,
+       9,    60,     5,    66,   205,    67,    62,    78,    68,   267,
+     214,    69,    82,   271,   273,   319,     5,   444,   243,    67,
+       5,   138,    68,   458,   459,     6,    70,     5,     5,   280,
+      67,     7,    79,    68,    71,   400,   470,   471,    72,     6,
+      73,    83,    84,     6,     8,     7,     9,    85,    86,     7,
+       6,     6,   134,   315,    73,    95,     7,     7,     8,   321,
+       9,    98,     8,    96,     9,    73,   102,   103,   104,     8,
+       8,     9,     9,   109,   114,   105,   107,   108,   113,   121,
+     118,   334,   117,   119,   124,   120,   123,   132,   142,   136,
+     340,   137,   131,   147,   140,   149,   150,   158,   152,   153,
+     159,   174,   165,   315,   164,   173,   177,   178,   179,   182,
+     194,   403,   186,   181,   183,   189,   187,   190,   377,   191,
+     192,   195,   193,   219,   232,   197,   239,   206,   214,   207,
+     403,   225,   242,   227,   228,   229,   230,   233,   231,   241,
+     248,   276,   429,   251,   403,   243,   253,   433,   247,   252,
+     148,   255,   258,   256,   269,   259,   266,   166,   270,   274,
+     275,   277,   278,   282,   283,   285,   286,   448,   287,   288,
+     289,   318,   388,   234,   310,   290,   311,   312,   322,   320,
+     323,   325,   326,   214,   327,   472,   338,   341,   337,   346,
+     345,   435,   214,   347,   350,   351,   355,   356,   352,   357,
+     367,   368,   380,   358,   381,   385,   393,   386,   413,   395,
+     397,   399,   404,   405,   406,   411,   377,   414,   417,   363,
+     423,   415,   420,   260,   422,   440,   377,   424,   427,   434,
+     443,   445,   377,   446,   475,   449,   447,   465,   377,   377,
+     450,   451,   377,   457,   462,   460,   461,   466,   268,   469,
+     408,   426,   125,   421,   456,   409,   452,   430,   100,     0,
+     353,     0,   313,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,   212
+};
+
+static const short yycheck[] =
+{
+       3,    46,   103,     3,    19,    19,   361,     9,    20,   276,
+       3,     8,   164,    65,    27,     6,    18,    69,    32,    31,
+      18,    38,    19,    23,   364,    18,     5,    40,    21,    22,
+      23,    24,    64,    12,    27,     0,    48,    40,    53,    41,
+      33,    34,    45,    41,    37,    47,    63,    40,    41,    47,
+     390,    11,    55,     3,    47,   322,    59,    17,   325,    65,
+      46,   416,    60,    56,    62,     8,    64,    60,    71,    62,
+     425,    57,    58,    23,    67,    19,    19,    27,   179,    66,
+     232,    65,    26,    16,   185,    69,    66,    90,    91,    36,
+      40,   358,    95,   360,    49,    98,    66,    65,    18,     3,
+     103,    69,   105,    18,   107,   108,   258,    65,    65,    65,
+      64,    69,    69,    69,    18,    68,    69,    21,    22,    23,
+      24,    41,     4,    27,    14,   128,    41,    47,   131,    33,
+      34,    65,    47,    37,    65,    69,    40,    41,    69,    66,
+      60,   449,    62,    47,    64,    60,   149,    62,    64,    64,
+      29,   459,    56,   254,    63,    65,    60,   465,    62,    69,
+     427,    68,    69,   471,   472,   168,   169,   475,    60,    61,
+     173,     3,    59,   176,    18,   178,   179,   180,   181,    67,
+     183,    18,   185,   450,    43,   337,    18,    68,    69,    66,
+      22,    23,    68,    69,    66,    27,    64,    41,   201,   202,
+      25,    33,    34,    47,    41,    37,    68,    69,    40,    41,
+      47,    68,    69,    68,    69,    47,    60,    65,    62,    64,
+      64,    68,    69,    60,    63,    62,    35,    64,    60,    67,
+      62,    51,    18,    19,   237,    21,    32,    64,    24,   242,
+     243,    27,    66,   246,   247,   290,    18,    68,    69,    21,
+      18,   254,    24,    68,    69,    41,    42,    18,    18,    19,
+      21,    47,    10,    24,    50,    37,    68,    69,    54,    41,
+      56,    65,    63,    41,    60,    47,    62,    64,    52,    47,
+      41,    41,   285,   286,    56,    67,    47,    47,    60,   292,
+      62,    67,    60,    39,    62,    56,    66,    64,    64,    60,
+      60,    62,    62,    66,    44,    64,    64,    64,    64,    15,
+      65,   314,    66,    63,    66,    64,    69,    45,    28,    66,
+     323,    65,    67,    65,    67,    64,    55,    64,    66,    65,
+      13,    19,    66,   336,    69,    67,    66,    64,    69,    30,
+      19,   386,    66,    69,    69,    66,    69,    66,   351,    65,
+      63,    65,    64,     7,    69,    66,    19,    66,   361,    66,
+     405,    65,    64,    66,    65,    63,    66,    66,    65,    65,
+      65,    64,   417,    65,   419,    69,    66,   422,    67,    65,
+     113,    66,    69,    65,    68,    66,    66,   128,    66,    66,
+      66,    66,    66,    66,    65,    64,    64,   442,    64,    66,
+      65,    62,     3,   201,    66,    69,    66,    65,    64,    66,
+      69,    64,    64,   416,    64,    70,    65,    65,    69,    64,
+      67,   424,   425,    66,    66,    64,    66,    65,    69,    66,
+      64,    66,    60,    69,    65,    64,    69,    64,    62,    69,
+      65,    67,    65,    64,    64,    64,   449,    65,    64,    40,
+      65,    68,    66,   237,    67,    65,   459,    69,    69,    66,
+      69,    65,   465,    68,    70,    67,    69,    67,   471,   472,
+      69,    69,   475,    65,    69,    65,    65,    65,   243,    66,
+     393,   411,    90,   405,   451,   393,   447,   419,    63,    -1,
+     336,    -1,   285,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,   178
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const unsigned char yystos[] =
+{
+       0,     6,    72,    64,     0,    18,    41,    47,    60,    62,
+     121,    65,    66,    16,    73,    66,    49,    82,    83,    36,
+      74,    66,   159,    14,    99,    64,     4,    75,    29,    84,
+      20,    31,    48,   160,    66,   110,    63,    64,    59,    78,
+      67,    43,    87,    66,    66,    64,   100,    25,   108,   124,
+      65,    63,    64,    35,    79,    64,    85,    86,   121,    67,
+      51,    90,    32,   168,   169,   121,    19,    21,    24,    27,
+      42,    50,    54,    56,   101,   104,   121,   136,    64,    10,
+     125,   143,    66,    65,    63,    64,    52,    76,   121,    68,
+      69,    64,    88,    89,   121,    67,    39,    92,    67,    19,
+     169,   161,    66,    64,    64,    64,   121,    64,    64,    66,
+       5,    12,   109,    64,    44,   144,   155,    66,    65,    63,
+      64,    15,    77,    69,    66,    86,   121,    68,    69,    91,
+     121,    67,    45,    95,   121,   170,    66,    65,   121,   141,
+      67,   121,    28,   105,   121,   141,   142,    65,   109,    64,
+      55,   156,    66,    65,    46,    57,    58,    81,    64,    13,
+      80,    60,    61,    98,    69,    66,    89,    68,    69,    64,
+      93,    94,   121,    67,    19,    68,    69,    66,    64,    69,
+     102,    69,    30,    69,    65,    69,    66,    69,   121,    66,
+      66,    65,    63,    64,    19,    65,    98,    66,   121,   121,
+      68,    69,    64,    96,    97,   121,    66,    66,   121,    38,
+      63,   162,   142,   141,   121,   122,   123,   107,   121,     7,
+     121,   141,   111,    11,    17,    65,   157,    66,    65,    63,
+      66,    65,    69,    66,    94,   121,    68,    69,   163,    19,
+      65,    65,    64,    69,   103,    65,    69,    67,    65,    19,
+      26,    65,    65,    66,   158,    66,    65,    98,    69,    66,
+      97,     9,    18,    41,    47,   164,    66,   121,   123,    68,
+      66,   121,   106,   121,    66,    66,    64,    66,    66,   145,
+      19,   141,    66,    65,    98,    64,    64,    64,    66,    65,
+      69,    68,    69,     3,    22,    23,    27,    33,    34,    37,
+      40,   113,   116,   118,   119,   120,   136,   127,   126,   146,
+      66,    66,    65,   170,    64,   121,   165,   166,    62,   136,
+      66,   121,    64,    69,   112,    64,    64,    64,     8,    19,
+     137,    19,    53,    65,   121,    65,    69,    69,    65,   113,
+     121,    65,   113,   113,   117,    67,    64,    66,     8,    19,
+      66,    64,    69,   166,    98,    66,    65,    66,    69,    65,
+      69,   114,    27,    40,   128,   129,   132,    64,    66,     3,
+      22,    23,    27,    33,    34,    37,    40,   121,   150,   152,
+      60,    65,   113,   113,   122,    64,    64,   112,     3,    23,
+     138,   139,   140,    69,   151,    69,   167,    65,   115,    67,
+      37,   133,   134,   136,    65,    64,    64,   112,   129,   139,
+     154,    64,   153,    62,    65,    68,   130,    64,    65,    69,
+      66,   133,    67,    65,    69,    67,   117,    69,   122,   136,
+     134,    65,   135,   136,    66,   121,   122,    65,   113,   131,
+      65,    68,    69,    69,    68,    65,    68,    69,   136,    67,
+      69,    69,   140,   147,   150,   113,   132,    65,    68,    69,
+      65,    65,    69,   148,   150,    67,    65,   149,   150,    66,
+      68,    69,    70,   150,   150,    70,   150
+};
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		-2
+#define YYEOF		0
+
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT		goto yyabortlab
+#define YYERROR		goto yyerrlab1
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+
+#define YYFAIL		goto yyerrlab
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)					\
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    {								\
+      yychar = (Token);						\
+      yylval = (Value);						\
+      yychar1 = YYTRANSLATE (yychar);				\
+      YYPOPSTACK;						\
+      goto yybackup;						\
+    }								\
+  else								\
+    { 								\
+      yyerror ("syntax error: cannot back up");			\
+      YYERROR;							\
+    }								\
+while (0)
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+   are run).  */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)           \
+  Current.first_line   = Rhs[1].first_line;      \
+  Current.first_column = Rhs[1].first_column;    \
+  Current.last_line    = Rhs[N].last_line;       \
+  Current.last_column  = Rhs[N].last_column;
+#endif
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#define YYLEX	yylex ()
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)			\
+do {						\
+  if (yydebug)					\
+    YYFPRINTF Args;				\
+} while (0)
+# define YYDSYMPRINT(Args)			\
+do {						\
+  if (yydebug)					\
+    yysymprint Args;				\
+} while (0)
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YYDSYMPRINT(Args)
+#endif /* !YYDEBUG */
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef	YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#if YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined (__GLIBC__) && defined (_STRING_H)
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+static YYSIZE_T
+#   if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+#   else
+yystrlen (yystr)
+     const char *yystr;
+#   endif
+{
+  register const char *yys = yystr;
+
+  while (*yys++ != '\0')
+    continue;
+
+  return yys - yystr - 1;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+static char *
+#   if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+#   else
+yystpcpy (yydest, yysrc)
+     char *yydest;
+     const char *yysrc;
+#   endif
+{
+  register char *yyd = yydest;
+  register const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+#endif /* !YYERROR_VERBOSE */
+
+
+
+#if YYDEBUG
+/*-----------------------------.
+| Print this symbol on YYOUT.  |
+`-----------------------------*/
+
+static void
+#if defined (__STDC__) || defined (__cplusplus)
+yysymprint (FILE* yyout, int yytype, YYSTYPE yyvalue)
+#else
+yysymprint (yyout, yytype, yyvalue)
+    FILE* yyout;
+    int yytype;
+    YYSTYPE yyvalue;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvalue;
+
+  if (yytype < YYNTOKENS)
+    {
+      YYFPRINTF (yyout, "token %s (", yytname[yytype]);
+# ifdef YYPRINT
+      YYPRINT (yyout, yytoknum[yytype], yyvalue);
+# endif
+    }
+  else
+    YYFPRINTF (yyout, "nterm %s (", yytname[yytype]);
+
+  switch (yytype)
+    {
+      default:
+        break;
+    }
+  YYFPRINTF (yyout, ")");
+}
+#endif /* YYDEBUG. */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+static void
+#if defined (__STDC__) || defined (__cplusplus)
+yydestruct (int yytype, YYSTYPE yyvalue)
+#else
+yydestruct (yytype, yyvalue)
+    int yytype;
+    YYSTYPE yyvalue;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvalue;
+
+  switch (yytype)
+    {
+      default:
+        break;
+    }
+}
+
+
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+   into yyparse.  The argument should have type void *.
+   It should actually point to an object.
+   Grammar actions can access the variable by casting it
+   to the proper pointer type.  */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+#  define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+#  define YYPARSE_PARAM_DECL
+# else
+#  define YYPARSE_PARAM_ARG YYPARSE_PARAM
+#  define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+# endif
+#else /* !YYPARSE_PARAM */
+# define YYPARSE_PARAM_ARG
+# define YYPARSE_PARAM_DECL
+#endif /* !YYPARSE_PARAM */
+
+/* Prevent warning if -Wstrict-prototypes.  */
+#ifdef __GNUC__
+# ifdef YYPARSE_PARAM
+int yyparse (void *);
+# else
+int yyparse (void);
+# endif
+#endif
+
+
+/* The lookahead symbol.  */
+int yychar;
+
+/* The semantic value of the lookahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of parse errors so far.  */
+int yynerrs;
+
+
+int
+yyparse (YYPARSE_PARAM_ARG)
+     YYPARSE_PARAM_DECL
+{
+  
+  register int yystate;
+  register int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Lookahead token as an internal (translated) token number.  */
+  int yychar1 = 0;
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  short	yyssa[YYINITDEPTH];
+  short *yyss = yyssa;
+  register short *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  register YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK   (yyvsp--, yyssp--)
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
+  /* When reducing, the number of symbols on the RHS of the reduced
+     rule.  */
+  int yylen;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed. so pushing a state here evens the stacks.
+     */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyssp >= yyss + yystacksize - 1)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+	/* Give user a chance to reallocate the stack. Use copies of
+	   these so that the &'s don't force the real ones into
+	   memory.  */
+	YYSTYPE *yyvs1 = yyvs;
+	short *yyss1 = yyss;
+
+
+	/* Each stack pointer address is followed by the size of the
+	   data in use in that stack, in bytes.  This used to be a
+	   conditional around just the two extra args, but that might
+	   be undefined if yyoverflow is a macro.  */
+	yyoverflow ("parser stack overflow",
+		    &yyss1, yysize * sizeof (*yyssp),
+		    &yyvs1, yysize * sizeof (*yyvsp),
+
+		    &yystacksize);
+
+	yyss = yyss1;
+	yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyoverflowlab;
+# else
+      /* Extend the stack our own way.  */
+      if (yystacksize >= YYMAXDEPTH)
+	goto yyoverflowlab;
+      yystacksize *= 2;
+      if (yystacksize > YYMAXDEPTH)
+	yystacksize = YYMAXDEPTH;
+
+      {
+	short *yyss1 = yyss;
+	union yyalloc *yyptr =
+	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+	if (! yyptr)
+	  goto yyoverflowlab;
+	YYSTACK_RELOCATE (yyss);
+	YYSTACK_RELOCATE (yyvs);
+
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+		  (unsigned long int) yystacksize));
+
+      if (yyssp >= yyss + yystacksize - 1)
+	YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state.  */
+/* Read a lookahead token if we need one and don't already have one.  */
+/* yyresume: */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* yychar is either YYEMPTY or YYEOF
+     or a valid token in external form.  */
+
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  /* Convert token to internal form (in yychar1) for indexing tables with.  */
+
+  if (yychar <= 0)		/* This means end of input.  */
+    {
+      yychar1 = 0;
+      yychar = YYEOF;		/* Don't call YYLEX any more.  */
+
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yychar1 = YYTRANSLATE (yychar);
+
+      /* We have to keep this `#if YYDEBUG', since we use variables
+	 which are defined only if `YYDEBUG' is set.  */
+      YYDPRINTF ((stderr, "Next token is "));
+      YYDSYMPRINT ((stderr, yychar1, yylval));
+      YYDPRINTF ((stderr, "\n"));
+    }
+
+  /* If the proper action on seeing token YYCHAR1 is to reduce or to
+     detect an error, take that action.  */
+  yyn += yychar1;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yychar1)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+	goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Shift the lookahead token.  */
+  YYDPRINTF ((stderr, "Shifting token %d (%s), ",
+	      yychar, yytname[yychar1]));
+
+  /* Discard the token being shifted unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  *++yyvsp = yylval;
+
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+
+
+#if YYDEBUG
+  /* We have to keep this `#if YYDEBUG', since we use variables which
+     are defined only if `YYDEBUG' is set.  */
+  if (yydebug)
+    {
+      int yyi;
+
+      YYFPRINTF (stderr, "Reducing via rule %d (line %d), ",
+		 yyn - 1, yyrline[yyn]);
+
+      /* Print the symbols being reduced, and their result.  */
+      for (yyi = yyprhs[yyn]; yyrhs[yyi] >= 0; yyi++)
+	YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
+      YYFPRINTF (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+    }
+#endif
+  switch (yyn)
+    {
+        case 2:
+#line 210 "dfgparser.y"
+    { string_StringFree(yyvsp[-7].string);
+					  YYACCEPT; /* Stop immediately */ }
+    break;
+
+  case 4:
+#line 230 "dfgparser.y"
+    { dfg_DESC.name = yyvsp[-2].string; }
+    break;
+
+  case 5:
+#line 234 "dfgparser.y"
+    { dfg_DESC.author = yyvsp[-2].string; }
+    break;
+
+  case 6:
+#line 238 "dfgparser.y"
+    { dfg_DESC.status = yyvsp[-2].state; }
+    break;
+
+  case 7:
+#line 242 "dfgparser.y"
+    { dfg_DESC.description = yyvsp[-2].string; }
+    break;
+
+  case 9:
+#line 247 "dfgparser.y"
+    { dfg_DESC.version = yyvsp[-2].string; }
+    break;
+
+  case 11:
+#line 252 "dfgparser.y"
+    { dfg_DESC.logic = yyvsp[-2].string; }
+    break;
+
+  case 13:
+#line 257 "dfgparser.y"
+    { dfg_DESC.date = yyvsp[-2].string; }
+    break;
+
+  case 14:
+#line 260 "dfgparser.y"
+    { yyval.state = DFG_SATISFIABLE; }
+    break;
+
+  case 15:
+#line 261 "dfgparser.y"
+    { yyval.state = DFG_UNSATISFIABLE; }
+    break;
+
+  case 16:
+#line 262 "dfgparser.y"
+    { yyval.state = DFG_UNKNOWNSTATE; }
+    break;
+
+  case 24:
+#line 299 "dfgparser.y"
+    { dfg_SymbolDecl(DFG_FUNC, yyvsp[0].string, -2); }
+    break;
+
+  case 25:
+#line 301 "dfgparser.y"
+    { dfg_SymbolDecl(DFG_FUNC, yyvsp[-3].string, yyvsp[-1].number); }
+    break;
+
+  case 30:
+#line 312 "dfgparser.y"
+    { dfg_SymbolDecl(DFG_PRDICAT, yyvsp[0].string, -2); }
+    break;
+
+  case 31:
+#line 313 "dfgparser.y"
+    { dfg_SymbolDecl(DFG_PRDICAT, yyvsp[-3].string, yyvsp[-1].number); }
+    break;
+
+  case 34:
+#line 320 "dfgparser.y"
+    { dfg_SymbolDecl(DFG_PRDICAT, yyvsp[0].string, 1); }
+    break;
+
+  case 35:
+#line 321 "dfgparser.y"
+    { dfg_SymbolDecl(DFG_PRDICAT, yyvsp[0].string, 1); }
+    break;
+
+  case 40:
+#line 332 "dfgparser.y"
+    { dfg_SymbolDecl(DFG_OPERAT, yyvsp[0].string, -2); }
+    break;
+
+  case 41:
+#line 333 "dfgparser.y"
+    { dfg_SymbolDecl(DFG_OPERAT, yyvsp[-3].string, yyvsp[-1].number); }
+    break;
+
+  case 46:
+#line 344 "dfgparser.y"
+    { dfg_SymbolDecl(DFG_QUANTIF, yyvsp[0].string, -2); }
+    break;
+
+  case 47:
+#line 345 "dfgparser.y"
+    { dfg_SymbolDecl(DFG_QUANTIF, yyvsp[-3].string, yyvsp[-1].number); }
+    break;
+
+  case 48:
+#line 348 "dfgparser.y"
+    { yyval.number = -1; }
+    break;
+
+  case 49:
+#line 349 "dfgparser.y"
+    { yyval.number = yyvsp[0].number; }
+    break;
+
+  case 55:
+#line 368 "dfgparser.y"
+    { dfg_SubSort(yyvsp[-4].string,yyvsp[-2].string); }
+    break;
+
+  case 56:
+#line 369 "dfgparser.y"
+    { dfg_SORTDECLLIST = list_Nconc(dfg_SORTDECLLIST,list_List(list_PairCreate(NULL,yyvsp[-1].term))); }
+    break;
+
+  case 57:
+#line 371 "dfgparser.y"
+    { string_StringFree(yyvsp[-4].string); }
+    break;
+
+  case 58:
+#line 372 "dfgparser.y"
+    { dfg_VarStart(); }
+    break;
+
+  case 59:
+#line 373 "dfgparser.y"
+    { dfg_VarStop();  }
+    break;
+
+  case 60:
+#line 374 "dfgparser.y"
+    { TERM term;
+					  dfg_VarBacktrack();
+					  dfg_VarCheck();
+					  term = dfg_CreateQuantifier(fol_All(),yyvsp[-6].list,yyvsp[-2].term);
+					  dfg_SORTDECLLIST = list_Nconc(dfg_SORTDECLLIST,list_List(list_PairCreate(NULL,term)));
+					}
+    break;
+
+  case 61:
+#line 383 "dfgparser.y"
+    { dfg_SymbolGenerated(dfg_Symbol(yyvsp[-7].string,1), yyvsp[-6].bool, yyvsp[-2].list); }
+    break;
+
+  case 62:
+#line 386 "dfgparser.y"
+    { yyval.bool = FALSE; }
+    break;
+
+  case 63:
+#line 387 "dfgparser.y"
+    { yyval.bool = TRUE; }
+    break;
+
+  case 64:
+#line 390 "dfgparser.y"
+    { yyval.list = list_List(yyvsp[0].string); }
+    break;
+
+  case 65:
+#line 391 "dfgparser.y"
+    { yyval.list = list_Cons(yyvsp[0].string, yyvsp[-2].list); }
+    break;
+
+  case 66:
+#line 394 "dfgparser.y"
+    { string_StringFree(yyvsp[0].string); }
+    break;
+
+  case 67:
+#line 395 "dfgparser.y"
+    { string_StringFree(yyvsp[0].string); }
+    break;
+
+  case 68:
+#line 404 "dfgparser.y"
+    { list_NReverse(yyvsp[-2].list);
+                                  if (yyvsp[-5].bool) /* Axioms */
+				    dfg_AXIOMLIST = list_Nconc(dfg_AXIOMLIST, yyvsp[-2].list);
+				  else
+				    dfg_CONJECLIST = list_Nconc(dfg_CONJECLIST, yyvsp[-2].list);
+				}
+    break;
+
+  case 69:
+#line 412 "dfgparser.y"
+    { yyval.bool = TRUE;  }
+    break;
+
+  case 70:
+#line 413 "dfgparser.y"
+    { yyval.bool = FALSE; }
+    break;
+
+  case 73:
+#line 420 "dfgparser.y"
+    { yyval.list = list_Nil(); }
+    break;
+
+  case 74:
+#line 422 "dfgparser.y"
+    { LIST pair;
+					  if (yyvsp[-3].term == NULL) { /* No term */
+					    if (yyvsp[-2].string != NULL)
+					      string_StringFree(yyvsp[-2].string);
+					    yyval.list = yyvsp[-6].list;
+					  } else {
+					    pair = list_PairCreate(yyvsp[-2].string, yyvsp[-3].term);
+					    yyval.list = list_Cons(pair, yyvsp[-6].list);
+					  }
+					  dfg_VarCheck();
+					}
+    break;
+
+  case 75:
+#line 435 "dfgparser.y"
+    { yyval.string = NULL; }
+    break;
+
+  case 76:
+#line 436 "dfgparser.y"
+    { yyval.string = yyvsp[0].string;   }
+    break;
+
+  case 77:
+#line 439 "dfgparser.y"
+    { yyval.term = yyvsp[0].term; }
+    break;
+
+  case 78:
+#line 441 "dfgparser.y"
+    { yyval.term = dfg_IGNORE ? NULL : term_Create(fol_Not(),list_List(yyvsp[-1].term)); }
+    break;
+
+  case 79:
+#line 443 "dfgparser.y"
+    { yyval.term = dfg_IGNORE ? NULL : term_Create(yyvsp[-5].symbol, list_Cons(yyvsp[-3].term, list_List(yyvsp[-1].term))); }
+    break;
+
+  case 80:
+#line 445 "dfgparser.y"
+    { yyval.term = dfg_IGNORE ? NULL : term_Create(yyvsp[-3].symbol, yyvsp[-1].list); }
+    break;
+
+  case 81:
+#line 446 "dfgparser.y"
+    { dfg_VarStart(); }
+    break;
+
+  case 82:
+#line 447 "dfgparser.y"
+    { dfg_VarStop(); }
+    break;
+
+  case 83:
+#line 449 "dfgparser.y"
+    { dfg_VarBacktrack();
+		    yyval.term = dfg_IGNORE ? NULL : dfg_CreateQuantifier(yyvsp[-9].symbol,yyvsp[-5].list,yyvsp[-1].term);
+		  }
+    break;
+
+  case 84:
+#line 454 "dfgparser.y"
+    { yyval.term = NULL; }
+    break;
+
+  case 85:
+#line 455 "dfgparser.y"
+    { yyval.term = yyvsp[0].term; }
+    break;
+
+  case 86:
+#line 459 "dfgparser.y"
+    { yyval.list = dfg_IGNORE ? list_Nil() : list_List(yyvsp[0].term); }
+    break;
+
+  case 87:
+#line 461 "dfgparser.y"
+    { yyval.list = dfg_IGNORE ? yyvsp[-2].list : list_Nconc(yyvsp[-2].list, list_List(yyvsp[0].term)); }
+    break;
+
+  case 88:
+#line 464 "dfgparser.y"
+    { yyval.symbol = fol_Equiv();    }
+    break;
+
+  case 89:
+#line 465 "dfgparser.y"
+    { yyval.symbol = fol_Implied();  }
+    break;
+
+  case 90:
+#line 466 "dfgparser.y"
+    { yyval.symbol = fol_Implies();  }
+    break;
+
+  case 91:
+#line 469 "dfgparser.y"
+    { yyval.symbol = fol_And(); }
+    break;
+
+  case 92:
+#line 470 "dfgparser.y"
+    { yyval.symbol = fol_Or();  }
+    break;
+
+  case 93:
+#line 473 "dfgparser.y"
+    { yyval.symbol = fol_Exist(); }
+    break;
+
+  case 94:
+#line 474 "dfgparser.y"
+    { yyval.symbol = fol_All(); }
+    break;
+
+  case 95:
+#line 477 "dfgparser.y"
+    { if (dfg_IGNORE) {
+  					    string_StringFree(yyvsp[0].string);
+					    yyval.string = NULL;
+					  } else
+					    yyval.string = yyvsp[0].string;
+					}
+    break;
+
+  case 96:
+#line 484 "dfgparser.y"
+    { yyval.string = dfg_IGNORE ? NULL : string_IntToString(yyvsp[0].number); }
+    break;
+
+  case 97:
+#line 486 "dfgparser.y"
+    { yyval.string = dfg_IGNORE ? NULL : string_StringCopy("set_flag"); }
+    break;
+
+  case 98:
+#line 488 "dfgparser.y"
+    { yyval.string = dfg_IGNORE ? NULL : string_StringCopy("set_DomPred"); }
+    break;
+
+  case 99:
+#line 490 "dfgparser.y"
+    { yyval.string = dfg_IGNORE ? NULL : string_StringCopy("set_precedence"); }
+    break;
+
+  case 100:
+#line 494 "dfgparser.y"
+    { yyval.list = dfg_IGNORE ? list_Nil() : list_List(yyvsp[0].term); }
+    break;
+
+  case 101:
+#line 496 "dfgparser.y"
+    { yyval.list = dfg_IGNORE ? yyvsp[-2].list : list_Nconc(yyvsp[-2].list, list_List(yyvsp[0].term)); }
+    break;
+
+  case 102:
+#line 500 "dfgparser.y"
+    { if (!dfg_IGNORE) {
+		      SYMBOL s = dfg_Symbol(yyvsp[0].string,0);
+		      if (!symbol_IsVariable(s)) {
+			misc_StartUserErrorReport();
+			misc_UserErrorReport("\n Line %d: Symbol is not a variable.\n",dfg_LINENUMBER);
+			misc_FinishUserErrorReport();
+		      }
+		      yyval.term = term_Create(s, list_Nil());
+		    }
+		  }
+    break;
+
+  case 103:
+#line 511 "dfgparser.y"
+    { if (!dfg_IGNORE) {
+		      SYMBOL p, v;
+		      p = dfg_Symbol(yyvsp[-3].string, 1);
+		      if (!symbol_IsPredicate(p)) {
+			misc_StartUserErrorReport();
+			misc_UserErrorReport("\n Line %d: Symbol is not a predicate.\n",dfg_LINENUMBER);
+			misc_FinishUserErrorReport();
+		      }
+		      v = dfg_Symbol(yyvsp[-1].string, 0);
+		      if (!symbol_IsVariable(v)) {
+			misc_StartUserErrorReport();
+			misc_UserErrorReport("\n Line %d: Symbol is not a variable.\n",dfg_LINENUMBER);
+			misc_FinishUserErrorReport();
+		      }
+		      yyval.term = term_Create(p, list_List(term_Create(v,list_Nil())));
+		    }
+		  }
+    break;
+
+  case 106:
+#line 541 "dfgparser.y"
+    { list_NReverse(yyvsp[-2].list);
+                    if (yyvsp[-7].bool) /* Axioms */
+		      dfg_AXCLAUSES = list_Nconc(dfg_AXCLAUSES, yyvsp[-2].list);
+		    else
+		      dfg_CONCLAUSES = list_Nconc(dfg_CONCLAUSES, yyvsp[-2].list);
+		  }
+    break;
+
+  case 107:
+#line 548 "dfgparser.y"
+    { stack_Push((POINTER)dfg_IGNORE); dfg_IGNORE = TRUE; }
+    break;
+
+  case 108:
+#line 551 "dfgparser.y"
+    { dfg_IGNORE = (BOOL)stack_PopResult(); }
+    break;
+
+  case 109:
+#line 554 "dfgparser.y"
+    { yyval.list = list_Nil(); }
+    break;
+
+  case 110:
+#line 556 "dfgparser.y"
+    { LIST pair;
+		    if (yyvsp[-3].term == NULL) { /* No clause */
+		      if (yyvsp[-2].string != NULL)
+			string_StringFree(yyvsp[-2].string);
+		      yyval.list = yyvsp[-6].list;
+		    } else {
+		      pair = list_PairCreate(yyvsp[-2].string, yyvsp[-3].term);
+		      yyval.list = list_Cons(pair, yyvsp[-6].list);
+		    }
+		    dfg_VarCheck();
+		  }
+    break;
+
+  case 111:
+#line 569 "dfgparser.y"
+    { yyval.term = NULL; }
+    break;
+
+  case 112:
+#line 570 "dfgparser.y"
+    { yyval.term = yyvsp[0].term; }
+    break;
+
+  case 113:
+#line 573 "dfgparser.y"
+    { yyval.term = yyvsp[0].term; }
+    break;
+
+  case 114:
+#line 574 "dfgparser.y"
+    { dfg_VarStart(); }
+    break;
+
+  case 115:
+#line 575 "dfgparser.y"
+    { dfg_VarStop();  }
+    break;
+
+  case 116:
+#line 577 "dfgparser.y"
+    { dfg_VarBacktrack();
+		    yyval.term = dfg_IGNORE ? NULL : dfg_CreateQuantifier(fol_All(),yyvsp[-5].list,yyvsp[-1].term);
+		  }
+    break;
+
+  case 117:
+#line 583 "dfgparser.y"
+    { yyval.term = dfg_IGNORE ? NULL : term_Create(fol_Or(), yyvsp[-1].list); }
+    break;
+
+  case 118:
+#line 587 "dfgparser.y"
+    { yyval.list = dfg_IGNORE ? list_Nil() : list_List(yyvsp[0].term); }
+    break;
+
+  case 119:
+#line 589 "dfgparser.y"
+    { yyval.list = dfg_IGNORE ? yyvsp[-2].list : list_Nconc(yyvsp[-2].list, list_List(yyvsp[0].term)); }
+    break;
+
+  case 120:
+#line 592 "dfgparser.y"
+    { yyval.term = yyvsp[0].term; }
+    break;
+
+  case 121:
+#line 594 "dfgparser.y"
+    { yyval.term = dfg_IGNORE ? yyvsp[-1].term : term_Create(fol_Not(),list_List(yyvsp[-1].term)); }
+    break;
+
+  case 122:
+#line 597 "dfgparser.y"
+    { yyval.list = list_List(yyvsp[0].term); }
+    break;
+
+  case 123:
+#line 598 "dfgparser.y"
+    { yyval.list = list_Nconc(yyvsp[-2].list, list_List(yyvsp[0].term)); }
+    break;
+
+  case 124:
+#line 602 "dfgparser.y"
+    { yyval.term = dfg_IGNORE ? NULL : dfg_AtomCreate(yyvsp[0].string,list_Nil()); }
+    break;
+
+  case 125:
+#line 604 "dfgparser.y"
+    { yyval.term = dfg_IGNORE ? NULL : term_Create(fol_True(),list_Nil()); }
+    break;
+
+  case 126:
+#line 606 "dfgparser.y"
+    { yyval.term = dfg_IGNORE ? NULL : term_Create(fol_False(),list_Nil()); }
+    break;
+
+  case 127:
+#line 608 "dfgparser.y"
+    { yyval.term = dfg_IGNORE ? NULL : term_Create(fol_Equality(),list_Cons(yyvsp[-3].term,list_List(yyvsp[-1].term))); }
+    break;
+
+  case 128:
+#line 610 "dfgparser.y"
+    { yyval.term = dfg_IGNORE ? NULL : dfg_AtomCreate(yyvsp[-3].string, yyvsp[-1].list); }
+    break;
+
+  case 136:
+#line 636 "dfgparser.y"
+    { yyval.term = dfg_IGNORE ? NULL : dfg_TermCreate(yyvsp[0].string,list_Nil()); }
+    break;
+
+  case 137:
+#line 638 "dfgparser.y"
+    { yyval.term = dfg_IGNORE ? NULL : dfg_TermCreate(yyvsp[-3].string, yyvsp[-1].list); }
+    break;
+
+  case 138:
+#line 642 "dfgparser.y"
+    { yyval.list = dfg_IGNORE ? list_Nil() : list_List(yyvsp[0].term); }
+    break;
+
+  case 139:
+#line 644 "dfgparser.y"
+    { yyval.list = dfg_IGNORE ? yyvsp[-2].list : list_Nconc(yyvsp[-2].list,list_List(yyvsp[0].term)); }
+    break;
+
+  case 142:
+#line 656 "dfgparser.y"
+    { if (!string_Equal(yyvsp[-2].string,"SPASS")) {
+		      stack_Push((POINTER)dfg_IGNORE);
+		      dfg_IGNORE = TRUE;
+		    }
+		  }
+    break;
+
+  case 143:
+#line 663 "dfgparser.y"
+    { if (!string_Equal(yyvsp[-6].string,"SPASS"))
+		      dfg_IGNORE = (BOOL)stack_PopResult();
+		    string_StringFree(yyvsp[-6].string);
+		  }
+    break;
+
+  case 145:
+#line 672 "dfgparser.y"
+    { if (!dfg_IGNORE && yyvsp[-11].string!=NULL && yyvsp[-9].term!=NULL && !list_Empty(yyvsp[-4].list)) {
+		    LIST tupel;
+		    RULE Rule = clause_GetOriginFromString(yyvsp[-7].string);
+		    string_StringFree(yyvsp[-7].string);
+		    /* Build a tuple (label,clause,parentlist,split level,origin) */
+		    tupel = list_Cons((POINTER)yyvsp[-2].number,list_List((POINTER)Rule));
+		    tupel = list_Cons(yyvsp[-11].string,list_Cons(yyvsp[-9].term,list_Cons(yyvsp[-4].list,tupel)));
+		    dfg_PROOFLIST = list_Cons(tupel, dfg_PROOFLIST);
+		  } else {
+		    /* ignore DNF clauses and clauses with incomplete data */
+		    if (yyvsp[-11].string != NULL) string_StringFree(yyvsp[-11].string);
+		    if (yyvsp[-9].term != NULL) term_Delete(yyvsp[-9].term);
+		    if (yyvsp[-7].string != NULL) string_StringFree(yyvsp[-7].string);
+		    dfg_DeleteStringList(yyvsp[-4].list);
+		  }
+		  dfg_VarCheck();
+		}
+    break;
+
+  case 146:
+#line 692 "dfgparser.y"
+    { yyval.list = (dfg_IGNORE||yyvsp[0].string==NULL) ? list_Nil() : list_List(yyvsp[0].string); }
+    break;
+
+  case 147:
+#line 694 "dfgparser.y"
+    { yyval.list = (dfg_IGNORE||yyvsp[0].string==NULL) ? yyvsp[-2].list : list_Nconc(yyvsp[-2].list, list_List(yyvsp[0].string)); }
+    break;
+
+  case 148:
+#line 698 "dfgparser.y"
+    { yyval.number = 0; }
+    break;
+
+  case 149:
+#line 699 "dfgparser.y"
+    { yyval.number = yyvsp[-1].number; }
+    break;
+
+  case 150:
+#line 703 "dfgparser.y"
+    { if (!dfg_IGNORE && yyvsp[-2].string!=NULL && yyvsp[0].string!=NULL && string_Equal(yyvsp[-2].string,"splitlevel"))
+		      string_StringToInt(yyvsp[0].string, TRUE, &yyval.number);
+		    else
+		      yyval.number = 0;
+		    if (yyvsp[-2].string != NULL) string_StringFree(yyvsp[-2].string);
+		    if (yyvsp[0].string != NULL) string_StringFree(yyvsp[0].string);
+		  }
+    break;
+
+  case 151:
+#line 711 "dfgparser.y"
+    { if (!dfg_IGNORE && yyvsp[-2].string!=NULL && yyvsp[0].string!=NULL && string_Equal(yyvsp[-2].string,"splitlevel"))
+		      string_StringToInt(yyvsp[0].string, TRUE, &yyval.number);
+		    else
+		      yyval.number = yyvsp[-4].number;
+		    if (yyvsp[-2].string != NULL) string_StringFree(yyvsp[-2].string);
+		    if (yyvsp[0].string != NULL) string_StringFree(yyvsp[0].string);
+		  }
+    break;
+
+  case 152:
+#line 721 "dfgparser.y"
+    { stack_Push((POINTER) dfg_IGNORE); dfg_IGNORE = TRUE; }
+    break;
+
+  case 153:
+#line 723 "dfgparser.y"
+    { dfg_IGNORE = (BOOL) stack_PopResult();
+		    if (yyvsp[0].bool) {
+		      if (yyvsp[-2].string != NULL) string_StringFree(yyvsp[-2].string);
+		      yyval.string = NULL;
+		    } else
+		      yyval.string = yyvsp[-2].string;
+		  }
+    break;
+
+  case 154:
+#line 732 "dfgparser.y"
+    { yyval.string = yyvsp[0].string; }
+    break;
+
+  case 155:
+#line 733 "dfgparser.y"
+    { yyval.string = NULL; }
+    break;
+
+  case 156:
+#line 734 "dfgparser.y"
+    { yyval.string = NULL; }
+    break;
+
+  case 157:
+#line 735 "dfgparser.y"
+    { yyval.string = NULL; }
+    break;
+
+  case 158:
+#line 736 "dfgparser.y"
+    { yyval.string = NULL; }
+    break;
+
+  case 159:
+#line 737 "dfgparser.y"
+    { yyval.string = NULL; }
+    break;
+
+  case 160:
+#line 738 "dfgparser.y"
+    { yyval.string = NULL; }
+    break;
+
+  case 161:
+#line 739 "dfgparser.y"
+    { yyval.string = NULL; }
+    break;
+
+  case 162:
+#line 740 "dfgparser.y"
+    { yyval.string = NULL; }
+    break;
+
+  case 163:
+#line 743 "dfgparser.y"
+    { yyval.bool = FALSE; }
+    break;
+
+  case 164:
+#line 744 "dfgparser.y"
+    { yyval.bool = TRUE; }
+    break;
+
+  case 165:
+#line 745 "dfgparser.y"
+    { yyval.bool = TRUE; }
+    break;
+
+  case 166:
+#line 748 "dfgparser.y"
+    { yyval.term = yyvsp[0].term;   }
+    break;
+
+  case 167:
+#line 749 "dfgparser.y"
+    { yyval.term = NULL; }
+    break;
+
+  case 170:
+#line 761 "dfgparser.y"
+    { dfg_VarStart(); }
+    break;
+
+  case 171:
+#line 762 "dfgparser.y"
+    {
+                                          dfg_VarStop();
+                                          dfg_VarBacktrack();
+                                          dfg_VarCheck(); }
+    break;
+
+  case 173:
+#line 769 "dfgparser.y"
+    { dfg_TERMLIST = list_Nconc(dfg_TERMLIST, list_List(yyvsp[-1].term)); }
+    break;
+
+  case 177:
+#line 781 "dfgparser.y"
+    { if (string_Equal(yyvsp[0].string,"SPASS"))
+					    dfg_IGNORETEXT = FALSE;
+					  string_StringFree(yyvsp[0].string);
+					}
+    break;
+
+  case 178:
+#line 786 "dfgparser.y"
+    { dfg_IGNORETEXT = TRUE; }
+    break;
+
+  case 179:
+#line 789 "dfgparser.y"
+    { /* no SPASS flags */
+				  string_StringFree(yyvsp[0].string);
+				}
+    break;
+
+  case 184:
+#line 801 "dfgparser.y"
+    { SYMBOL s;
+		    for ( ; !list_Empty(yyvsp[-1].list); yyvsp[-1].list = list_Pop(yyvsp[-1].list)) {
+		      s = symbol_Lookup(list_Car(yyvsp[-1].list));
+		      if (s == 0) {
+		        misc_StartUserErrorReport();
+		        misc_UserErrorReport("\n Undefined symbol %s", list_Car(yyvsp[-1].list));
+			misc_UserErrorReport(" in DomPred list.\n"); 
+			misc_FinishUserErrorReport(); 
+		      }
+		      if (!symbol_IsPredicate(s)) {
+			misc_StartUserErrorReport();
+			misc_UserErrorReport("\n Symbol %s isn't a predicate", list_Car(yyvsp[-1].list));
+			misc_UserErrorReport(" in DomPred list.\n");
+			misc_FinishUserErrorReport();
+		      }
+		      string_StringFree(list_Car(yyvsp[-1].list)); 
+		      symbol_AddProperty(s, DOMPRED);
+		    }
+		  }
+    break;
+
+  case 185:
+#line 821 "dfgparser.y"
+    { int flag = flag_Id(yyvsp[-3].string);
+		    if (flag == -1) {
+		      misc_StartUserErrorReport();
+		      misc_UserErrorReport("\n Found unknown flag %s", yyvsp[-3].string);
+		      misc_FinishUserErrorReport();
+		    }
+		    string_StringFree(yyvsp[-3].string);
+		    flag_SetFlagValue(dfg_FLAGS, flag, yyvsp[-1].number);
+		  }
+    break;
+
+  case 188:
+#line 837 "dfgparser.y"
+    { SYMBOL s = symbol_Lookup(yyvsp[0].string);
+		      if (s == 0) {
+			misc_StartUserErrorReport();
+			misc_UserErrorReport("\n Undefined symbol %s ", yyvsp[0].string);
+			misc_UserErrorReport(" in precedence list.\n"); 
+			misc_FinishUserErrorReport(); 
+		      }
+		      string_StringFree(yyvsp[0].string);
+		      symbol_SetIncreasedOrdering(dfg_PRECEDENCE, s);
+                      dfg_USERPRECEDENCE = list_Cons((POINTER)s, dfg_USERPRECEDENCE);
+		    }
+    break;
+
+  case 189:
+#line 849 "dfgparser.y"
+    { SYMBOL s = symbol_Lookup(yyvsp[-4].string);
+		      if (s == 0) {
+			misc_StartUserErrorReport();
+			misc_UserErrorReport("\n Undefined symbol %s", yyvsp[-4].string);
+			misc_UserErrorReport("in precedence list.\n");
+			misc_FinishUserErrorReport(); 
+		      }
+		      string_StringFree(yyvsp[-4].string);
+		      symbol_SetIncreasedOrdering(dfg_PRECEDENCE, s);
+                      dfg_USERPRECEDENCE = list_Cons((POINTER)s, dfg_USERPRECEDENCE);
+		      symbol_SetWeight(s, yyvsp[-2].number);
+		      if (yyvsp[-1].property != 0)
+			symbol_AddProperty(s, yyvsp[-1].property);
+		    }
+    break;
+
+  case 190:
+#line 865 "dfgparser.y"
+    { yyval.property = 0; /* left */ }
+    break;
+
+  case 191:
+#line 867 "dfgparser.y"
+    { if (yyvsp[0].string[1] != '\0' ||
+			  (yyvsp[0].string[0]!='l' && yyvsp[0].string[0]!='m' && yyvsp[0].string[0]!='r')) {
+		         misc_StartUserErrorReport();
+			 misc_UserErrorReport("\n Invalid symbol status %s", yyvsp[0].string);
+			 misc_UserErrorReport(" in precedence list.");
+			 misc_FinishUserErrorReport();
+		      }
+		      switch (yyvsp[0].string[0]) {
+		      case 'm': yyval.property = ORDMUL;   break;
+		      case 'r': yyval.property = ORDRIGHT; break;
+		      default:  yyval.property = 0;
+		      }
+		      string_StringFree(yyvsp[0].string);
+		    }
+    break;
+
+  case 194:
+#line 888 "dfgparser.y"
+    { dfg_DeleteStringList(yyvsp[-2].list); }
+    break;
+
+  case 195:
+#line 891 "dfgparser.y"
+    { yyval.list = list_List(yyvsp[0].string); }
+    break;
+
+  case 196:
+#line 892 "dfgparser.y"
+    { yyval.list = list_Nconc(yyvsp[-2].list, list_List(yyvsp[0].string)); }
+    break;
+
+
+    }
+
+/* Line 1016 of /opt/gnu//share/bison/yacc.c.  */
+#line 2471 "dfgparser.c"
+
+  yyvsp -= yylen;
+  yyssp -= yylen;
+
+
+#if YYDEBUG
+  if (yydebug)
+    {
+      short *yyssp1 = yyss - 1;
+      YYFPRINTF (stderr, "state stack now");
+      while (yyssp1 != yyssp)
+	YYFPRINTF (stderr, " %d", *++yyssp1);
+      YYFPRINTF (stderr, "\n");
+    }
+#endif
+
+  *++yyvsp = yyval;
+
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if YYERROR_VERBOSE
+      yyn = yypact[yystate];
+
+      if (YYPACT_NINF < yyn && yyn < YYLAST)
+	{
+	  YYSIZE_T yysize = 0;
+	  int yytype = YYTRANSLATE (yychar);
+	  char *yymsg;
+	  int yyx, yycount;
+
+	  yycount = 0;
+	  /* Start YYX at -YYN if negative to avoid negative indexes in
+	     YYCHECK.  */
+	  for (yyx = yyn < 0 ? -yyn : 0;
+	       yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
+	    if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+	      yysize += yystrlen (yytname[yyx]) + 15, yycount++;
+	  yysize += yystrlen ("parse error, unexpected ") + 1;
+	  yysize += yystrlen (yytname[yytype]);
+	  yymsg = (char *) YYSTACK_ALLOC (yysize);
+	  if (yymsg != 0)
+	    {
+	      char *yyp = yystpcpy (yymsg, "parse error, unexpected ");
+	      yyp = yystpcpy (yyp, yytname[yytype]);
+
+	      if (yycount < 5)
+		{
+		  yycount = 0;
+		  for (yyx = yyn < 0 ? -yyn : 0;
+		       yyx < (int) (sizeof (yytname) / sizeof (char *));
+		       yyx++)
+		    if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+		      {
+			const char *yyq = ! yycount ? ", expecting " : " or ";
+			yyp = yystpcpy (yyp, yyq);
+			yyp = yystpcpy (yyp, yytname[yyx]);
+			yycount++;
+		      }
+		}
+	      yyerror (yymsg);
+	      YYSTACK_FREE (yymsg);
+	    }
+	  else
+	    yyerror ("parse error; also virtual memory exhausted");
+	}
+      else
+#endif /* YYERROR_VERBOSE */
+	yyerror ("parse error");
+    }
+  goto yyerrlab1;
+
+
+/*----------------------------------------------------.
+| yyerrlab1 -- error raised explicitly by an action.  |
+`----------------------------------------------------*/
+yyerrlab1:
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse lookahead token after an
+	 error, discard it.  */
+
+      /* Return failure if at end of input.  */
+      if (yychar == YYEOF)
+        {
+	  /* Pop the error token.  */
+          YYPOPSTACK;
+	  /* Pop the rest of the stack.  */
+	  while (yyssp > yyss)
+	    {
+	      YYDPRINTF ((stderr, "Error: popping "));
+	      YYDSYMPRINT ((stderr,
+			    yystos[*yyssp],
+			    *yyvsp));
+	      YYDPRINTF ((stderr, "\n"));
+	      yydestruct (yystos[*yyssp], *yyvsp);
+	      YYPOPSTACK;
+	    }
+	  YYABORT;
+        }
+
+      YYDPRINTF ((stderr, "Discarding token %d (%s).\n",
+		  yychar, yytname[yychar1]));
+      yydestruct (yychar1, yylval);
+      yychar = YYEMPTY;
+    }
+
+  /* Else will try to reuse lookahead token after shifting the error
+     token.  */
+
+  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+	{
+	  yyn += YYTERROR;
+	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+	    {
+	      yyn = yytable[yyn];
+	      if (0 < yyn)
+		break;
+	    }
+	}
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+	YYABORT;
+
+      YYDPRINTF ((stderr, "Error: popping "));
+      YYDSYMPRINT ((stderr,
+		    yystos[*yyssp], *yyvsp));
+      YYDPRINTF ((stderr, "\n"));
+
+      yydestruct (yystos[yystate], *yyvsp);
+      yyvsp--;
+      yystate = *--yyssp;
+
+
+#if YYDEBUG
+      if (yydebug)
+	{
+	  short *yyssp1 = yyss - 1;
+	  YYFPRINTF (stderr, "Error: state stack now");
+	  while (yyssp1 != yyssp)
+	    YYFPRINTF (stderr, " %d", *++yyssp1);
+	  YYFPRINTF (stderr, "\n");
+	}
+#endif
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  YYDPRINTF ((stderr, "Shifting error token, "));
+
+  *++yyvsp = yylval;
+
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#ifndef yyoverflow
+/*----------------------------------------------.
+| yyoverflowlab -- parser overflow comes here.  |
+`----------------------------------------------*/
+yyoverflowlab:
+  yyerror ("parser stack overflow");
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+  return yyresult;
+}
+
+
+#line 895 "dfgparser.y"
+
+
+void yyerror(const char *s)
+{
+  misc_StartUserErrorReport();
+  misc_UserErrorReport("\n Line %i: %s\n", dfg_LINENUMBER, s);
+  misc_FinishUserErrorReport();
+}
+
+static void dfg_Init(FILE* Input, FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   The input file stream for the parser, a flag store and
+           a precedence.
+  RETURNS: Nothing.
+  EFFECT:  The parser and scanner are initialized.
+           The parser will use the flag store and the precedence
+	   to memorize the settings from the input file.
+***************************************************************/
+{
+  extern FILE* dfg_in;  /* declared in dfgscanner */
+
+  dfg_in               = Input;
+  dfg_LINENUMBER       = 1;
+  dfg_IGNORETEXT       = TRUE;
+  dfg_AXIOMLIST        = list_Nil();
+  dfg_CONJECLIST       = list_Nil();
+  dfg_SORTDECLLIST     = list_Nil();
+  dfg_USERPRECEDENCE   = list_Nil();
+  dfg_AXCLAUSES        = list_Nil();
+  dfg_CONCLAUSES       = list_Nil();
+  dfg_PROOFLIST        = list_Nil();
+  dfg_TERMLIST         = list_Nil();
+  dfg_SYMBOLLIST       = list_Nil();
+  dfg_VARLIST          = list_Nil();
+  dfg_VARDECL          = FALSE;
+  dfg_IGNORE           = FALSE;
+  dfg_FLAGS            = Flags;
+  dfg_PRECEDENCE       = Precedence;
+  dfg_DESC.name        = (char*) NULL;
+  dfg_DESC.author      = (char*) NULL;
+  dfg_DESC.version     = (char*) NULL;
+  dfg_DESC.logic       = (char*) NULL;
+  dfg_DESC.status      = DFG_UNKNOWNSTATE;
+  dfg_DESC.description = (char*) NULL;
+  dfg_DESC.date        = (char*) NULL;
+}
+
+
+void dfg_Free(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: Nothing.
+  EFFECT:  Frees memory used by the problem description.
+***************************************************************/
+{
+  if (dfg_DESC.name != NULL)
+    string_StringFree(dfg_DESC.name);
+  if (dfg_DESC.author != NULL)
+    string_StringFree(dfg_DESC.author);
+  if (dfg_DESC.version != NULL)
+    string_StringFree(dfg_DESC.version);
+  if (dfg_DESC.logic != NULL)
+    string_StringFree(dfg_DESC.logic);
+  if (dfg_DESC.description != NULL)
+    string_StringFree(dfg_DESC.description);
+  if(dfg_DESC.date != NULL)
+    string_StringFree(dfg_DESC.date);
+}
+
+const char* dfg_ProblemName(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: The problem's name from the description section.
+***************************************************************/
+{
+  return dfg_DESC.name;
+}
+
+const char* dfg_ProblemAuthor(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: The problem's author from the description section.
+***************************************************************/
+{
+  return dfg_DESC.author;
+}
+
+const char* dfg_ProblemVersion(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: The problem's version from the description section.
+***************************************************************/
+{
+  return dfg_DESC.version;
+}
+
+const char* dfg_ProblemLogic(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: The problem's logic from the description section.
+***************************************************************/
+{
+  return dfg_DESC.logic;
+}
+
+DFG_STATE dfg_ProblemStatus(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: The problem's status from the description section.
+***************************************************************/
+{
+  return dfg_DESC.status;
+}
+
+const char* dfg_ProblemStatusString(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: The string representation of the problem's status.
+***************************************************************/
+{
+  const char* result = "";
+
+  switch (dfg_DESC.status) {
+  case DFG_SATISFIABLE:
+    result = "satisfiable"; break;
+  case DFG_UNSATISFIABLE:
+    result = "unsatisfiable"; break;
+  case DFG_UNKNOWNSTATE:
+    result = "unknown"; break;
+  default:
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In dfg_ProblemStatusString: Invalid status.\n");
+    misc_FinishErrorReport();
+  }
+  return result;
+}
+
+const char* dfg_ProblemDescription(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: The problem's description from the description section.
+***************************************************************/
+{
+  return dfg_DESC.description;
+}
+
+const char* dfg_ProblemDate(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: The problem's date from the description section.
+***************************************************************/
+{
+  return dfg_DESC.date;
+}
+
+void dfg_FPrintDescription(FILE* File)
+/**************************************************************
+  INPUT:   A file stream.
+  RETURNS: Nothing.
+  EFFECT:  The description section from the input file
+           is printed to 'File'. You must call the parser first
+           before calling this function.
+***************************************************************/
+{
+  fputs("list_of_descriptions.\n  name(", File);
+  if (dfg_DESC.name != NULL)
+    fputs(dfg_DESC.name, File);
+  else
+    fputs("{* *}", File);
+  fputs(").\n  author(", File);
+  if (dfg_DESC.author != NULL)
+    fputs(dfg_DESC.author, File);
+  else
+    fputs("{* *}", File);
+  fputs(").\n", File);
+  if (dfg_DESC.version != NULL) {
+    fputs("  version(", File);
+    fputs(dfg_DESC.version, File);
+    fputs(").\n", File);
+  }
+  if (dfg_DESC.logic != NULL) {
+    fputs("  logic(", File);
+    fputs(dfg_DESC.logic, File);
+    fputs(").\n", File);
+  }
+  fputs("  status(", File);
+  fputs(dfg_ProblemStatusString(), File);
+  fputs(").\n  description(", File);
+  if (dfg_DESC.description != NULL)
+    fputs(dfg_DESC.description, File);
+  else
+    fputs("{* *}", File);
+  fputs(").\n", File);
+  if (dfg_DESC.date != NULL) {
+    fputs("  date(", File);
+    fputs(dfg_DESC.date, File);
+    fputs(").\n", File);
+  }
+  fputs("end_of_list.", File);
+}
+
+
+LIST dfg_DFGParser(FILE* File, FLAGSTORE Flags, PRECEDENCE Precedence,
+		   LIST* Axioms, LIST* Conjectures, LIST* SortDecl,
+		   LIST* UserDefinedPrecedence)
+/**************************************************************
+  INPUT:   The input file containing clauses or formulae in DFG syntax,
+           a flag store and a precedence used to memorize settings
+	   from the file.
+           Axioms, Conjectures, SortDecl and UserDefinedPrecedence are
+	   pointers to lists used as return values.
+  RETURNS: The list of clauses from File.
+  EFFECT:  Reads formulae and clauses from the input file.
+           The axioms, conjectures, sort declarations and user-defined
+	   precedences are appended to the respective lists, the lists
+	   are not deleted!
+	   All lists except the clause list contain pairs
+	   (label, term), where <label> may be NULL, if no
+	   label was specified for that term.
+	   <UserDefinedPrecedence> contains symbols sorted by decreasing
+	   precedence. This list will only be changed, if the precedence
+	   is explicitly defined in the input file. This can be done
+	   by the 'set_precedence' flag in the SPASS settings list in
+	   the DFG input file.
+  CAUTION: The weight of the clauses is not correct and the literals
+           are not oriented!
+***************************************************************/
+{
+  LIST  scan, tupel;
+  TERM  clauseTerm;
+  NAT   bottom;
+
+  dfg_Init(File, Flags, Precedence);  /* Initialize the parser and scanner */
+  bottom = stack_Bottom();
+  dfg_parse();          /* Invoke the parser */
+#ifdef CHECK 
+  if (!stack_Empty(bottom)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In dfg_DFGParser: Stack not empty!\n");
+    misc_FinishErrorReport();
+  }
+#endif
+  dfg_SymCleanUp();
+
+  /* Remove clause labels and create clauses from the terms */
+  for (scan = dfg_AXCLAUSES; !list_Empty(scan); scan = list_Cdr(scan)) {
+    tupel = list_Car(scan);
+    clauseTerm = list_PairSecond(tupel);
+    list_Rplaca(scan, dfg_CreateClauseFromTerm(clauseTerm,TRUE, Flags, Precedence));
+    if (list_PairFirst(tupel) != NULL)        /* Label is defined */
+      string_StringFree(list_PairFirst(tupel));  /* Delete the label */
+    list_PairFree(tupel);
+  }
+  /* Since dfg_CreateClauseFromTerm() returns NULL for trivial tautologies */
+  /* we now delete those NULL pointers from the clause list.               */
+  dfg_AXCLAUSES = list_PointerDeleteElement(dfg_AXCLAUSES, NULL);
+  for (scan = dfg_CONCLAUSES; !list_Empty(scan); scan = list_Cdr(scan)) {
+    tupel = list_Car(scan);
+    clauseTerm = list_PairSecond(tupel);
+    list_Rplaca(scan, dfg_CreateClauseFromTerm(clauseTerm,FALSE, Flags, Precedence));
+    if (list_PairFirst(tupel) != NULL)        /* Label is defined */
+      string_StringFree(list_PairFirst(tupel));  /* Delete the label */
+    list_PairFree(tupel);
+  }
+  /* Since dfg_CreateClauseFromTerm() returns NULL for trivial tautologies */
+  /* we now delete those NULL pointers from the clause list.               */
+  dfg_CONCLAUSES = list_PointerDeleteElement(dfg_CONCLAUSES, NULL);
+
+  /* Delete the proof list */
+  dfg_DeleteProofList(dfg_PROOFLIST);
+
+  /* Delete the list_of_terms, since it'll be ignored */
+  term_DeleteTermList(dfg_TERMLIST);
+
+  scan = list_Nconc(dfg_AXCLAUSES, dfg_CONCLAUSES);
+
+  *Axioms      = list_Nconc(*Axioms, dfg_AXIOMLIST);
+  *Conjectures = list_Nconc(*Conjectures, dfg_CONJECLIST);
+  *SortDecl    = list_Nconc(*SortDecl, dfg_SORTDECLLIST);
+  list_NReverse(dfg_USERPRECEDENCE);
+  *UserDefinedPrecedence = list_Nconc(*UserDefinedPrecedence, dfg_USERPRECEDENCE);
+
+  return scan;
+}
+
+
+LIST dfg_ProofParser(FILE* File, FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   The input file containing clauses in DFG syntax,
+           a flag store and a precedence used to memorize settings
+           from the file.
+  RETURNS: A list of tuples (label,clause,justificationlist,splitlevel,origin)
+           representing a proof.
+  EFFECT:  Reads inputs clauses with labels and the proof lists
+           from the input file.
+           The elements of the list are lists with five items.
+	   1. the label (a string) of a clause,
+	   2. the clause in TERM format,
+           3. the list of justification labels (strings, too),
+           4. the split level of the clause,
+           5. the origin of the clause (RULE struct from clause.h).
+	   Note that the justification list is empty for input
+	   clauses.
+***************************************************************/
+{
+  LIST  scan, tupel;
+  TERM  term;
+  NAT   bottom;
+
+  dfg_Init(File, Flags, Precedence);  /* Initialize the parser and scanner */
+  bottom = stack_Bottom();
+  dfg_parse();          /* Invoke the parser */
+#ifdef CHECK 
+  if (!stack_Empty(bottom)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In dfg_ProofParser: Stack not empty!\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  dfg_SymCleanUp();
+
+  /* Build the union of axiom and conjecture clauses */
+  dfg_AXCLAUSES  = list_Nconc(dfg_AXCLAUSES, dfg_CONCLAUSES);
+  dfg_CONCLAUSES = list_Nil();
+  for (scan = dfg_AXCLAUSES; !list_Empty(scan); scan = list_Cdr(scan)) {
+    tupel = list_Car(scan);
+    term  = list_PairSecond(tupel);
+    if (list_PairFirst(tupel) == NULL) {
+      /* Ignore input clauses without label */
+      term_Delete(term);
+      list_PairFree(tupel);
+      list_Rplaca(scan, NULL);
+    } else
+      /* Expand the pair to a tuple                            */
+      /* (label,clause,justificationlist, split level, origin) */
+      /* For input clauses the justificationlist is empty.     */
+      /* Input clauses have split level 0.                     */
+      list_Rplacd(tupel, list_Cons(term,list_Cons(list_Nil(),list_Cons(0, list_List((POINTER)INPUT)))));
+  }
+  /* Now delete the list items without labels */
+  dfg_AXCLAUSES = list_PointerDeleteElement(dfg_AXCLAUSES, NULL);
+
+  /* Delete the formula lists */
+  dfg_DeleteFormulaPairList(dfg_AXIOMLIST);
+  dfg_DeleteFormulaPairList(dfg_CONJECLIST);
+  /* Delete the list of sort declarations */
+  dfg_DeleteFormulaPairList(dfg_SORTDECLLIST);
+  /* Delete the list_of_terms, since it'll be ignored */
+  term_DeleteTermList(dfg_TERMLIST);
+
+  /* Finally append the proof list to the list of input clauses with labels */
+  dfg_PROOFLIST = list_NReverse(dfg_PROOFLIST);
+  dfg_AXCLAUSES = list_Nconc(dfg_AXCLAUSES, dfg_PROOFLIST);
+
+  return dfg_AXCLAUSES;
+}
+
+
+LIST dfg_TermParser(FILE* File, FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   The input file containing a list of terms in DFG syntax,
+           a flag store and a precedence used to memorize settings
+	   from the file.
+  RETURNS: The list of terms from <File>.
+  EFFECT:  Reads terms from the list_of_terms from the input file.
+***************************************************************/
+{
+  NAT bottom;
+  
+  dfg_Init(File, Flags, Precedence);   /* Initialize the parser and scanner */
+  bottom = stack_Bottom();
+  dfg_parse();          /* Invoke the parser */
+#ifdef CHECK 
+  if (!stack_Empty(bottom)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In dfg_TermParser: Stack not empty!\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  dfg_SymCleanUp();
+
+  /* Delete the clause lists */
+  dfg_DeleteFormulaPairList(dfg_AXCLAUSES);
+  dfg_DeleteFormulaPairList(dfg_CONCLAUSES);
+  /* Delete the formula lists */
+  dfg_DeleteFormulaPairList(dfg_AXIOMLIST);
+  dfg_DeleteFormulaPairList(dfg_CONJECLIST);
+  /* Delete the proof list */
+  dfg_DeleteProofList(dfg_PROOFLIST);
+  /* Delete the list of sort declarations */
+  dfg_DeleteFormulaPairList(dfg_SORTDECLLIST);
+
+  return dfg_TERMLIST;
+}
+
+
+void dfg_DeleteFormulaPairList(LIST FormulaPairs)
+/**************************************************************
+  INPUT:   A list of pairs (label, formula).
+  RETURNS: Nothing.
+  EFFECT:  The list and the pairs with their strings and terms
+           are completely deleted.
+***************************************************************/
+{
+  LIST pair;
+
+  for ( ; !list_Empty(FormulaPairs); FormulaPairs = list_Pop(FormulaPairs)) {
+    pair = list_Car(FormulaPairs);  /* (label, term) */
+    term_Delete(list_PairSecond(pair));
+    if (list_PairFirst(pair) != NULL)
+      string_StringFree(list_PairFirst(pair));  /* Free the label */
+    list_PairFree(pair);
+  }
+}
+
+void dfg_StripLabelsFromList(LIST FormulaPairs)
+/**************************************************************
+  INPUT:   A list of pairs (label, formula).
+  RETURNS: Nothing.
+  EFFECT:  The pairs are replaced by the respective formula
+           and the pairs with their label strings are deleted.
+***************************************************************/
+{
+  LIST pair, scan;
+
+  for (scan = FormulaPairs; !list_Empty(scan); scan = list_Cdr(scan)) {
+    pair = list_Car(scan);  /* (label, term) */
+    list_Rplaca(scan, list_PairSecond(pair));
+    if (list_PairFirst(pair) != NULL)
+      string_StringFree(list_PairFirst(pair));  /* Free the label */
+    list_PairFree(pair);
+  }
+}
+
+void dfg_DeleteProofList(LIST Proof)
+/**************************************************************
+  INPUT:   A list of tuples (label, term, justificationlist, split level).
+  RETURNS: Nothing.
+  EFFECT:  All memory used by the proof list is freed.
+           The labels must NOT be NULL entries!
+***************************************************************/
+{
+  /* Delete the proof list */
+  for ( ; !list_Empty(Proof); Proof = list_Pop(Proof)) {
+    LIST tupel = list_Car(Proof);
+    string_StringFree(list_First(tupel));
+    term_Delete(list_Second(tupel));
+    dfg_DeleteStringList(list_Third(tupel));
+    list_Delete(tupel);
+  }
+}
+
+/**************************************************************/
+/* Static Functions                                           */
+/**************************************************************/
+
+static void dfg_SymbolDecl(int SymbolType, char* Name, int Arity)
+/**************************************************************
+  INPUT:   The type of a symbol, the name, and the arity.
+  RETURNS: Nothing.
+  EFFECT:  This function handles the declaration of symbols.
+           If <Arity> is -2, it means that the arity of the symbol
+	   was not specified, if it is -1 the symbol is declared
+	   with arbitrary arity. User defined symbols with arbitrary
+           arity are not allowed.
+	   The <Name> is deleted.
+***************************************************************/
+{
+  NAT    arity, length;
+  SYMBOL symbol;
+
+  switch (Arity) {
+  case -2: /* not specified */
+    arity = 0;
+    break;
+  case -1:
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n Line %u: symbols with arbitrary arity are not allowed.\n",
+	    dfg_LINENUMBER);
+    misc_FinishUserErrorReport();
+  default:
+    arity = Arity;
+}
+
+  /* Pay attention to the maximum symbol name length */
+  length = strlen(Name);
+  if (length >= symbol__SYMBOLMAXLEN)
+    Name[symbol__SYMBOLMAXLEN-1] = '\0';
+
+  /* Check if this symbol was declared earlier */
+  symbol = symbol_Lookup(Name);
+  if (symbol != 0) {
+    /* Symbol was declared before */
+    /* Check if the old and new symbol type are equal */
+    if ((SymbolType == DFG_FUNC && !symbol_IsFunction(symbol)) ||
+	(SymbolType == DFG_PRDICAT && !symbol_IsPredicate(symbol)) ||
+	((SymbolType == DFG_OPERAT || SymbolType == DFG_QUANTIF) && 
+	 !symbol_IsJunctor(symbol))) {
+      misc_StartUserErrorReport();
+      misc_UserErrorReport("\n Line %u: symbol %s was already declared as ",
+	      dfg_LINENUMBER, Name);
+      switch (symbol_Type(symbol)) {
+      case symbol_CONSTANT:
+      case symbol_FUNCTION:
+	misc_UserErrorReport("function.\n"); break;
+      case symbol_PREDICATE:
+	misc_UserErrorReport("predicate.\n"); break;
+      case symbol_JUNCTOR:
+	misc_UserErrorReport("junctor.\n"); break;
+      default:
+	misc_UserErrorReport("unknown type.\n");
+      }
+      misc_FinishUserErrorReport();
+    }
+    /* Now check the old and new arity if specified */
+    if (Arity != -2 && Arity != symbol_Arity(symbol)) {
+      misc_StartUserErrorReport();
+      misc_UserErrorReport("\n Line %u: symbol %s was already declared with arity %d\n",
+			   dfg_LINENUMBER, Name, symbol_Arity(symbol));
+      misc_FinishUserErrorReport();
+    }
+  } else {
+    /* Symbol was not declared before */
+    switch (SymbolType) {
+    case DFG_FUNC:
+      symbol = symbol_CreateFunction(Name, arity, symbol_STATLEX,dfg_PRECEDENCE);
+      break;
+    case DFG_PRDICAT:
+      symbol = symbol_CreatePredicate(Name, arity,symbol_STATLEX,dfg_PRECEDENCE);
+      break;
+    default:
+      symbol = symbol_CreateJunctor(Name, arity, symbol_STATLEX, dfg_PRECEDENCE);
+    }
+    if (Arity == -2)
+      /* Arity wasn't specified so check the arity for each occurrence */
+      dfg_SymAdd(symbol);
+  }
+
+  if (length >= symbol__SYMBOLMAXLEN) {
+    /* To avoid a memory error restore the old string length */
+    Name[symbol__SYMBOLMAXLEN-1] = ' ';  /* Something != '\0' */
+  }
+  string_StringFree(Name);  /* Name was copied */
+}
+
+
+static SYMBOL dfg_Symbol(char* Name, NAT Arity)
+/**************************************************************
+  INPUT:   The name of a symbol and the actual arity of the symbol.
+  RETURNS: The corresponding SYMBOL.
+  EFFECT:  This function checks if the <Name> was declared as
+           symbol or variable. If not, an error message is printed
+	   to stderr.
+	   The <Name> is deleted.
+***************************************************************/
+{
+  SYMBOL symbol;
+  char   old;
+  NAT    length;
+
+  old = ' ';  /* Just to avoid a compiler warning */
+  /* Pay attention to the maximum symbol name length */
+  length = strlen(Name);
+  if (length >= symbol__SYMBOLMAXLEN) {
+    old = Name[symbol__SYMBOLMAXLEN-1];
+    Name[symbol__SYMBOLMAXLEN-1] = '\0';
+  }
+
+  symbol = symbol_Lookup(Name);
+  if (length >= symbol__SYMBOLMAXLEN) {
+    /* To avoid a memory error restore the old string */
+    Name[symbol__SYMBOLMAXLEN-1] = old;
+  }
+  if (symbol != 0) {
+    string_StringFree(Name);
+    dfg_SymCheck(symbol, Arity); /* Check the arity */
+  } else {
+    /* Variable */
+    if (Arity > 0) {
+      misc_StartUserErrorReport();
+      misc_UserErrorReport("\n Line %d: Undefined symbol %s.\n",dfg_LINENUMBER,Name);
+      misc_FinishUserErrorReport();
+    }
+    symbol = dfg_VarLookup(Name);
+  }
+  return symbol;
+}
+
+
+TERM dfg_CreateQuantifier(SYMBOL Symbol, LIST VarTermList, TERM Term)
+/**************************************************************
+  INPUT:   A quantifier symbol, a list possibly containing sorts,
+           and a term.
+  RETURNS: The created quantifier term..
+***************************************************************/
+{
+  LIST varlist, sortlist, scan;
+  TERM helpterm;
+
+  /* First collect the variable symbols in varlist and the sorts in sortlist */
+  varlist = sortlist = list_Nil();
+  for ( ; !list_Empty(VarTermList); VarTermList = list_Pop(VarTermList)) {
+    helpterm = list_Car(VarTermList);
+    if (term_IsVariable(helpterm)) {
+      varlist = list_Nconc(varlist, list_List((POINTER)term_TopSymbol(helpterm)));
+      term_Delete(helpterm);
+    } else {
+      SYMBOL var = term_TopSymbol(term_FirstArgument(helpterm));
+      varlist  = list_Nconc(varlist, list_List((POINTER)var));
+      sortlist = list_Nconc(sortlist, list_List(helpterm));
+    }
+  }
+
+  varlist = list_PointerDeleteDuplicates(varlist);
+  /* Now create terms from the variables */
+  for (scan = varlist; !list_Empty(scan); scan = list_Cdr(scan))
+    list_Rplaca(scan, term_Create((SYMBOL)list_Car(scan), list_Nil()));
+
+  if (!list_Empty(sortlist)) {
+    if (symbol_Equal(fol_All(), Symbol)) {
+      /* The conjunction of all sortterms implies the Term */
+      if (symbol_Equal(fol_Or(), term_TopSymbol(Term))) {
+	/* Special treatment if <Term> is a term with "or" like */
+	/* in clauses: add all sort terms negated to the args    */
+	/* of the "or" */
+	for (scan = sortlist; !list_Empty(scan); scan = list_Cdr(scan))
+	  /* Negate the sort terms */
+	  list_Rplaca(scan, term_Create(fol_Not(), list_List(list_Car(scan))));
+	sortlist = list_Nconc(sortlist, term_ArgumentList(Term));
+	term_RplacArgumentList(Term, sortlist);
+      } else {
+	/* No "or" term, so build the implication term */
+	if (list_Empty(list_Cdr(sortlist))) {
+	  /* Only one sort term */
+	  list_Rplacd(sortlist, list_List(Term));
+	  Term = term_Create(fol_Implies(), sortlist);
+	} else {
+	  /* More than one sort term */
+	  helpterm = term_Create(fol_And(), sortlist);
+	  Term = term_Create(fol_Implies(), list_Cons(helpterm, list_List(Term)));
+	}
+      }
+    } else if (symbol_Equal(fol_Exist(), Symbol)) {
+      /* Quantify the conjunction of all sort terms and <Term> */
+      if (symbol_Equal(fol_And(), term_TopSymbol(Term))) {
+	/* Special treatment if <Term> has an "and" as top symbol: */
+	/* just add the sort terms to the args of the "and".       */
+	sortlist = list_Nconc(sortlist, term_ArgumentList(Term));
+	term_RplacArgumentList(Term, sortlist);
+      } else {
+	sortlist = list_Nconc(sortlist, list_List(Term));
+	Term = term_Create(fol_And(), sortlist);
+      }
+    }
+  }
+  helpterm = fol_CreateQuantifier(Symbol, varlist, list_List(Term));
+  return helpterm;
+}
+
+
+CLAUSE dfg_CreateClauseFromTerm(TERM Clause, BOOL IsAxiom, FLAGSTORE Flags,
+				PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause term, a boolean value, a flag store and a precedence.
+  RETURNS: The clause term converted to a CLAUSE or NULL if the
+           clause is a trivial tautology (the clause contains
+	   the literal "true" or "not(false)" ).
+  EFFECT:  This function converts a clause stored as term into an
+           EARL clause structure.
+	   If 'IsAxiom' is TRUE the clause is treated as axiom
+	   clause else as conjecture clause.
+           The function deletes the literals "false" and "not(true)"
+           if they occur in <Clause>.
+	   The contents of the flag store and the precedence are changed
+	   because the parser read flag and precedence settings from
+	   
+  MEMORY:  The clause term is deleted.
+***************************************************************/
+{
+  LIST   literals, scan;
+  TERM   literal;
+  CLAUSE result;
+  
+  if (term_TopSymbol(Clause) == fol_All()) {
+    /* Remove and free the quantifier and the OR term */
+    literals = term_ArgumentList(term_SecondArgument(Clause));
+    term_RplacArgumentList(term_SecondArgument(Clause), list_Nil());
+  } else {
+    /* Remove and free the OR term */
+    literals = term_ArgumentList(Clause);
+    term_RplacArgumentList(Clause, list_Nil());
+  }
+  term_Delete(Clause);
+
+  for (scan = literals; !list_Empty(scan); scan = list_Cdr(scan)) {
+    literal = (TERM) list_Car(scan);
+    if (symbol_IsPredicate(term_TopSymbol(literal))) {  /* Positive literal */
+      if (fol_IsTrue(literal)) {
+	/* Clause is a tautology */
+	list_PointerDeleteElement(literals, NULL);
+	/* Remove possible NULL elements to avoid a crash in term_Delete */
+	term_DeleteTermList(literals);
+	return (CLAUSE) NULL;
+      } else if (fol_IsFalse(literal)) {
+	/* Ignore this literal */
+	term_Delete(literal);
+	list_Rplaca(scan, NULL); /* Mark the actual list element */
+      }
+    } else {
+      /* Found a negative literal */
+      TERM atom = term_FirstArgument(literal);
+      if (fol_IsFalse(atom)) {
+	/* Clause is a tautology */
+	list_PointerDeleteElement(literals, NULL);
+	/* Remove possible NULL elements to avoid a crash in term_Delete */
+	term_DeleteTermList(literals);
+	return (CLAUSE) NULL;
+      } else if (fol_IsTrue(atom)) {
+	/* Ignore this literal */
+	term_Delete(literal);
+	list_Rplaca(literals, NULL); /* Mark the actual list element */
+      }
+    }
+  }
+
+  literals = list_PointerDeleteElement(literals, NULL);
+  /* Remove the special literals treated above from the list */
+  result = clause_CreateFromLiterals(literals, FALSE, !IsAxiom, FALSE, Flags, Precedence);
+  /* Don't create sorts! */
+  list_Delete(literals);
+
+  return result;
+}
+
+
+static void dfg_SubSort(char* Name1, char* Name2)
+/**************************************************************
+  INPUT:   Two sort symbol names.
+  RETURNS: Nothing.
+  EFFECT:  This functions adds the formula
+           forall([U], implies(Name1(U), Name2(U)))
+	   to the list of axiom formulas. Both <Name1> and <Name2>
+	   are deleted.
+***************************************************************/
+{
+  SYMBOL s1, s2;
+  TERM   varterm, t1, t2, term;
+
+  s1 = dfg_Symbol(Name1, 1);   /* Should be unary predicates */
+  s2 = dfg_Symbol(Name2, 1);
+  if (!symbol_IsPredicate(s1)) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n Line %d: Symbol is not a sort predicate.\n", dfg_LINENUMBER);
+    misc_FinishUserErrorReport();
+  }
+  if (!symbol_IsPredicate(s2)) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n Line %d: Symbol is not a sort predicate.\n", dfg_LINENUMBER);
+    misc_FinishUserErrorReport();
+  }
+
+  varterm = term_Create(symbol_CreateStandardVariable(), list_Nil());
+  symbol_ResetStandardVarCounter();
+  
+  t1   = term_Create(s1, list_List(varterm));
+  t2   = term_Create(s2, list_List(term_Copy(varterm)));
+  term = term_Create(fol_Implies(), list_Cons(t1, list_List(t2)));
+  term = fol_CreateQuantifier(fol_All(), list_List(term_Copy(varterm)),
+			      list_List(term));
+  dfg_SORTDECLLIST = list_Nconc(dfg_SORTDECLLIST, list_List(list_PairCreate(NULL,term)));
+}
+
+
+static void dfg_SymbolGenerated(SYMBOL SortPredicate, BOOL FreelyGenerated,
+				LIST GeneratedBy)
+/**************************************************************
+  INPUT:   A sort predicate, a boolean flag, and a list of function
+           symbol names.
+  RETURNS: Nothing.
+  EFFECT:  This function stores the information that the <SortPredicate>
+           is generated by the function symbols from the <GeneratedBy>
+           list. The list contains only symbol names!
+	   The <SortPredicate> AND the symbols from the list get
+           the property GENERATED. Additionally the symbols get
+	   the property FREELY, if the flag <FreelyGenerated> is TRUE.
+***************************************************************/
+{
+  SYMBOL symbol;
+  LIST   scan;
+
+  if (!symbol_IsPredicate(SortPredicate)) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n Line %d: Symbol is not a sort predicate.\n", dfg_LINENUMBER);
+    misc_FinishUserErrorReport();
+  }
+  /* First reset the old information */
+  symbol_RemoveProperty(SortPredicate, GENERATED);
+  symbol_RemoveProperty(SortPredicate, FREELY);
+  list_Delete(symbol_GeneratedBy(SortPredicate));
+  /* Now set the new information */
+  symbol_AddProperty(SortPredicate, GENERATED);
+  if (FreelyGenerated)
+    symbol_AddProperty(SortPredicate, FREELY);
+  for (scan = GeneratedBy; !list_Empty(scan); scan = list_Cdr(scan)) {
+    symbol = symbol_Lookup(list_Car(scan));
+    if (symbol == 0) {
+      misc_StartUserErrorReport();
+      misc_UserErrorReport("\n Line %d: undefined symbol %s.\n", dfg_LINENUMBER,
+			   (char*)list_Car(scan));
+      misc_FinishUserErrorReport();
+    } else if (!symbol_IsFunction(symbol)) { /* must be function or constant */
+      misc_StartUserErrorReport();
+      misc_UserErrorReport("\n Line %d: Symbol is not a function.\n", dfg_LINENUMBER);
+      misc_FinishUserErrorReport();
+    }
+    string_StringFree(list_Car(scan));
+    list_Rplaca(scan, (POINTER)symbol);  /* change the name list to a symbol list */
+    /* Set GENERATED properties for generating symbols */
+    symbol_AddProperty(symbol, GENERATED);
+    if (FreelyGenerated)
+      symbol_AddProperty(symbol, FREELY);
+  }
+  symbol_SetGeneratedBy(SortPredicate, GeneratedBy);
+}
+
+
+/**************************************************************/
+/* Functions for the Symbol Table                             */
+/**************************************************************/
+
+typedef struct {
+  SYMBOL symbol;
+  BOOL   valid;
+  int    arity;
+} DFG_SYMENTRY, *DFG_SYM;
+
+static __inline__ DFG_SYM dfg_SymCreate(void)
+{
+  return (DFG_SYM) memory_Malloc(sizeof(DFG_SYMENTRY));
+}
+
+static __inline__ void dfg_SymFree(DFG_SYM Entry)
+{
+  memory_Free(Entry, sizeof(DFG_SYMENTRY));
+}
+
+
+static void dfg_SymAdd(SYMBOL Symbol)
+/**************************************************************
+  INPUT:   A symbol.
+  RETURNS: Nothing.
+  EFFECT:  This function adds 'Symbol' to the symbol list.
+           The arity of these symbols will be checked every time
+	   the symbol occurs.
+***************************************************************/
+{
+  DFG_SYM newEntry = dfg_SymCreate();
+  newEntry->symbol = Symbol;
+  newEntry->valid  = FALSE;
+  newEntry->arity  = 0;
+  dfg_SYMBOLLIST = list_Cons(newEntry, dfg_SYMBOLLIST);
+}
+
+
+static void dfg_SymCheck(SYMBOL Symbol, NAT Arity)
+/**************************************************************
+  INPUT:   A symbol and the current arity of this symbol.
+  RETURNS: Nothing.
+  EFFECT:  This function compares the previous arity of 'Symbol'
+           with the actual 'Arity'. If these values differ
+	   the symbol's arity is set to arbitrary.
+	   The arity of symbols whose arity was specified in
+	   the symbol declaration section is checked and a warning
+	   is printed to stderr in case of differences.
+***************************************************************/
+{
+  LIST scan = dfg_SYMBOLLIST;
+  while (!list_Empty(scan)) {
+    DFG_SYM actEntry = (DFG_SYM) list_Car(scan);
+    if (actEntry->symbol == Symbol) {
+      if (actEntry->valid) {
+	if (actEntry->arity != Arity) {
+	  misc_StartUserErrorReport();
+	  misc_UserErrorReport("\n Line %u:", dfg_LINENUMBER);
+	  misc_UserErrorReport(" The actual arity %u", Arity);
+	  misc_UserErrorReport(" of symbol %s differs", symbol_Name(Symbol));
+	  misc_UserErrorReport(" from the previous arity %u.\n", actEntry->arity);
+	  misc_FinishUserErrorReport();
+	}
+      } else {
+	/* Not valid => first time */
+	actEntry->arity = Arity;
+	actEntry->valid = TRUE;
+      }
+      return;
+    }
+    scan = list_Cdr(scan);
+  }
+
+  /* Symbol isn't in SymbolList, so its arity was specified.        */
+  /* Check if the specified arity corresponds with the actual arity */
+  if (symbol_Arity(Symbol) != Arity) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n Line %u: Symbol %s was declared with arity %u.\n",
+			 dfg_LINENUMBER, symbol_Name(Symbol), symbol_Arity(Symbol));
+    misc_FinishUserErrorReport();
+  }
+}
+
+
+static void dfg_SymCleanUp(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: Nothing.
+  EFFECT:  This function corrects all symbols whose arity wasn't
+           specified in the symbol declaration section but seem
+	   to occur with always the same arity.
+	   The memory for the symbol list is freed.
+***************************************************************/
+{
+  while (!list_Empty(dfg_SYMBOLLIST)) {
+    DFG_SYM actEntry  = (DFG_SYM) list_Car(dfg_SYMBOLLIST);
+    SYMBOL  actSymbol = actEntry->symbol;
+
+    if (actEntry->arity != symbol_Arity(actSymbol))
+      symbol_SetArity(actSymbol, actEntry->arity);
+
+    dfg_SymFree(actEntry);
+    dfg_SYMBOLLIST = list_Pop(dfg_SYMBOLLIST);
+  }
+}
+
+
+/**************************************************************/
+/* Functions for the Variable Table                           */
+/**************************************************************/
+  
+typedef struct {
+  char*  name;
+  SYMBOL symbol;
+} DFG_VARENTRY, *DFG_VAR;
+
+static __inline__ char* dfg_VarName(DFG_VAR Entry)
+{
+  return Entry->name;
+}
+
+static __inline__ SYMBOL dfg_VarSymbol(DFG_VAR Entry)
+{
+  return Entry->symbol;
+}
+
+static __inline__ DFG_VAR dfg_VarCreate(void)
+{
+  return (DFG_VAR) memory_Malloc(sizeof(DFG_VARENTRY));
+}
+
+static void dfg_VarFree(DFG_VAR Entry)
+{
+  string_StringFree(Entry->name);
+  memory_Free(Entry, sizeof(DFG_VARENTRY));
+}
+
+static void dfg_VarStart(void)
+{
+  dfg_VARLIST = list_Push(list_Nil(), dfg_VARLIST);
+  dfg_VARDECL = TRUE;
+}
+
+static void dfg_VarStop(void)
+{
+  dfg_VARDECL = FALSE;
+}
+
+static void dfg_VarBacktrack(void)
+{
+  list_DeleteWithElement(list_Top(dfg_VARLIST), (void (*)(POINTER)) dfg_VarFree);
+  dfg_VARLIST = list_Pop(dfg_VARLIST);
+}
+
+static void dfg_VarCheck(void)
+/* Should be called after a complete clause or formula was parsed */
+{
+  if (!list_Empty(dfg_VARLIST)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In dfg_VarCheck: List of variables should be empty!\n");
+    misc_FinishErrorReport();
+  }
+  symbol_ResetStandardVarCounter();
+}
+
+static SYMBOL dfg_VarLookup(char* Name)
+/**************************************************************
+  INPUT:   A variable name.
+  RETURNS: The corresponding variable symbol.
+  EFFECT:  If the variable name was quantified before, the
+           corresponding symbol is returned and the <Name> is freed.
+	   If the variable name was not quantified, and <dfg_VARDECL>
+	   is TRUE, a new variable is created, else an error
+	   message is printed and the program exits.
+***************************************************************/
+{
+  LIST   scan, scan2;
+  SYMBOL symbol = symbol_Null();
+
+  scan  = dfg_VARLIST;
+  scan2 = list_Nil();
+  while (!list_Empty(scan) && list_Empty(scan2)) {
+    scan2 = list_Car(scan);
+    while (!list_Empty(scan2) &&
+	   (!string_Equal(dfg_VarName(list_Car(scan2)), Name)))
+      scan2 = list_Cdr(scan2);
+    scan = list_Cdr(scan);
+  }
+
+  if (!list_Empty(scan2)) {
+    /* Found variable */
+    string_StringFree(Name);
+    symbol = dfg_VarSymbol(list_Car(scan2));
+  } else {
+    /* Variable not found */
+    if (dfg_VARDECL) {
+      DFG_VAR newEntry = dfg_VarCreate();
+      newEntry->name   = Name;
+      newEntry->symbol = symbol_CreateStandardVariable();
+      /* Add <newentry> to the first list in dfg_VARLIST */
+      list_Rplaca(dfg_VARLIST, list_Cons(newEntry,list_Car(dfg_VARLIST)));
+      symbol = dfg_VarSymbol(newEntry);
+    } else {
+      misc_StartUserErrorReport();
+      misc_UserErrorReport("\n Line %u: Free Variable %s.\n", dfg_LINENUMBER, Name);
+      misc_FinishUserErrorReport();
+    }
+  }
+  return symbol;
+}
+
diff --git a/test/spass/dfgparser.h b/test/spass/dfgparser.h
new file mode 100644
index 0000000000000000000000000000000000000000..252f1409c891ecbec04131ad072dbfe7ac887c29
--- /dev/null
+++ b/test/spass/dfgparser.h
@@ -0,0 +1,184 @@
+/* A Bison parser, made from dfgparser.y, by GNU bison 1.75.  */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 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, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+#ifndef BISON_DFGPARSER_H
+# define BISON_DFGPARSER_H
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     DFG_AND = 258,
+     DFG_AUTHOR = 259,
+     DFG_AXIOMS = 260,
+     DFG_BEGPROB = 261,
+     DFG_BY = 262,
+     DFG_CLAUSE = 263,
+     DFG_CLOSEBRACE = 264,
+     DFG_CLSLIST = 265,
+     DFG_CNF = 266,
+     DFG_CONJECS = 267,
+     DFG_DATE = 268,
+     DFG_DECLLIST = 269,
+     DFG_DESC = 270,
+     DFG_DESCLIST = 271,
+     DFG_DNF = 272,
+     DFG_DOMPRED = 273,
+     DFG_ENDLIST = 274,
+     DFG_ENDPROB = 275,
+     DFG_EQUAL = 276,
+     DFG_EQUIV = 277,
+     DFG_EXISTS = 278,
+     DFG_FALSE = 279,
+     DFG_FORMLIST = 280,
+     DFG_FORMULA = 281,
+     DFG_FORALL = 282,
+     DFG_FREELY = 283,
+     DFG_FUNC = 284,
+     DFG_GENERATED = 285,
+     DFG_GENSET = 286,
+     DFG_HYPOTH = 287,
+     DFG_IMPLIED = 288,
+     DFG_IMPLIES = 289,
+     DFG_LOGIC = 290,
+     DFG_NAME = 291,
+     DFG_NOT = 292,
+     DFG_OPENBRACE = 293,
+     DFG_OPERAT = 294,
+     DFG_OR = 295,
+     DFG_PREC = 296,
+     DFG_PRED = 297,
+     DFG_PRDICAT = 298,
+     DFG_PRFLIST = 299,
+     DFG_QUANTIF = 300,
+     DFG_SATIS = 301,
+     DFG_SETFLAG = 302,
+     DFG_SETTINGS = 303,
+     DFG_SYMLIST = 304,
+     DFG_SORT = 305,
+     DFG_SORTS = 306,
+     DFG_STATUS = 307,
+     DFG_STEP = 308,
+     DFG_SUBSORT = 309,
+     DFG_TERMLIST = 310,
+     DFG_TRUE = 311,
+     DFG_UNKNOWN = 312,
+     DFG_UNSATIS = 313,
+     DFG_VERSION = 314,
+     DFG_NUM = 315,
+     DFG_MINUS1 = 316,
+     DFG_ID = 317,
+     DFG_TEXT = 318
+   };
+#endif
+#define DFG_AND 258
+#define DFG_AUTHOR 259
+#define DFG_AXIOMS 260
+#define DFG_BEGPROB 261
+#define DFG_BY 262
+#define DFG_CLAUSE 263
+#define DFG_CLOSEBRACE 264
+#define DFG_CLSLIST 265
+#define DFG_CNF 266
+#define DFG_CONJECS 267
+#define DFG_DATE 268
+#define DFG_DECLLIST 269
+#define DFG_DESC 270
+#define DFG_DESCLIST 271
+#define DFG_DNF 272
+#define DFG_DOMPRED 273
+#define DFG_ENDLIST 274
+#define DFG_ENDPROB 275
+#define DFG_EQUAL 276
+#define DFG_EQUIV 277
+#define DFG_EXISTS 278
+#define DFG_FALSE 279
+#define DFG_FORMLIST 280
+#define DFG_FORMULA 281
+#define DFG_FORALL 282
+#define DFG_FREELY 283
+#define DFG_FUNC 284
+#define DFG_GENERATED 285
+#define DFG_GENSET 286
+#define DFG_HYPOTH 287
+#define DFG_IMPLIED 288
+#define DFG_IMPLIES 289
+#define DFG_LOGIC 290
+#define DFG_NAME 291
+#define DFG_NOT 292
+#define DFG_OPENBRACE 293
+#define DFG_OPERAT 294
+#define DFG_OR 295
+#define DFG_PREC 296
+#define DFG_PRED 297
+#define DFG_PRDICAT 298
+#define DFG_PRFLIST 299
+#define DFG_QUANTIF 300
+#define DFG_SATIS 301
+#define DFG_SETFLAG 302
+#define DFG_SETTINGS 303
+#define DFG_SYMLIST 304
+#define DFG_SORT 305
+#define DFG_SORTS 306
+#define DFG_STATUS 307
+#define DFG_STEP 308
+#define DFG_SUBSORT 309
+#define DFG_TERMLIST 310
+#define DFG_TRUE 311
+#define DFG_UNKNOWN 312
+#define DFG_UNSATIS 313
+#define DFG_VERSION 314
+#define DFG_NUM 315
+#define DFG_MINUS1 316
+#define DFG_ID 317
+#define DFG_TEXT 318
+
+
+
+
+#ifndef YYSTYPE
+#line 165 "dfgparser.y"
+typedef union {
+  int       number;
+  char*     string;
+  SYMBOL    symbol;
+  SPROPERTY property;
+  TERM      term;
+  LIST      list;
+  DFG_STATE state;
+  BOOL      bool;
+} yystype;
+/* Line 1281 of /opt/gnu//share/bison/yacc.c.  */
+#line 177 "dfgparser.h"
+# define YYSTYPE yystype
+#endif
+
+extern YYSTYPE dfg_lval;
+
+
+#endif /* not BISON_DFGPARSER_H */
+
diff --git a/test/spass/dfgscanner.c b/test/spass/dfgscanner.c
new file mode 100644
index 0000000000000000000000000000000000000000..a6eefa46aed07373aecbf65326da0ff93c2779ed
--- /dev/null
+++ b/test/spass/dfgscanner.c
@@ -0,0 +1,5174 @@
+#define yy_create_buffer dfg__create_buffer
+#define yy_delete_buffer dfg__delete_buffer
+#define yy_scan_buffer dfg__scan_buffer
+#define yy_scan_string dfg__scan_string
+#define yy_scan_bytes dfg__scan_bytes
+#define yy_flex_debug dfg__flex_debug
+#define yy_init_buffer dfg__init_buffer
+#define yy_flush_buffer dfg__flush_buffer
+#define yy_load_buffer_state dfg__load_buffer_state
+#define yy_switch_to_buffer dfg__switch_to_buffer
+#define yyin dfg_in
+#define yyleng dfg_leng
+#define yylex dfg_lex
+#define yyout dfg_out
+#define yyrestart dfg_restart
+#define yytext dfg_text
+
+#line 19 "dfgscanner.c"
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header$
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif	/* __STDC__ */
+#endif	/* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator).  This
+ * avoids problems with code like:
+ *
+ * 	if ( condition_holds )
+ *		yyless( 5 );
+ *	else
+ *		do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+		*yy_cp = yy_hold_char; \
+		YY_RESTORE_YY_MORE_OFFSET \
+		yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+	};
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1;		/* whether we need to initialize */
+static int yy_start = 0;	/* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! yy_current_buffer ) \
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	yy_current_buffer->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! yy_current_buffer ) \
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	yy_current_buffer->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+
+#define yywrap() 1
+#define YY_SKIP_YYWRAP
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+static yyconst short yy_nxt[][41] =
+    {
+    {
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0
+    },
+
+    {
+        5,    6,    7,    8,    9,   10,   11,   12,   13,   13,
+       14,   14,   14,   14,   15,   16,   17,   18,   19,   20,
+       21,   22,   23,   14,   14,   24,   14,   25,   26,   27,
+       28,   14,   29,   30,   31,   32,   14,   14,   14,   33,
+        6
+
+    },
+
+    {
+        5,    6,    7,    8,    9,   10,   11,   12,   13,   13,
+       14,   14,   14,   14,   15,   16,   17,   18,   19,   20,
+       21,   22,   23,   14,   14,   24,   14,   25,   26,   27,
+       28,   14,   29,   30,   31,   32,   14,   14,   14,   33,
+        6
+    },
+
+    {
+        5,   34,   34,   34,   34,   34,   35,   34,   34,   34,
+       34,   34,   34,   34,   34,   34,   34,   34,   34,   34,
+       34,   34,   34,   34,   34,   34,   34,   34,   34,   34,
+       34,   34,   34,   34,   34,   34,   34,   34,   34,   34,
+       34
+
+    },
+
+    {
+        5,   34,   34,   34,   34,   34,   35,   34,   34,   34,
+       34,   34,   34,   34,   34,   34,   34,   34,   34,   34,
+       34,   34,   34,   34,   34,   34,   34,   34,   34,   34,
+       34,   34,   34,   34,   34,   34,   34,   34,   34,   34,
+       34
+    },
+
+    {
+       -5,   -5,   -5,   -5,   -5,   -5,   -5,   -5,   -5,   -5,
+       -5,   -5,   -5,   -5,   -5,   -5,   -5,   -5,   -5,   -5,
+       -5,   -5,   -5,   -5,   -5,   -5,   -5,   -5,   -5,   -5,
+       -5,   -5,   -5,   -5,   -5,   -5,   -5,   -5,   -5,   -5,
+       -5
+
+    },
+
+    {
+        5,   -6,   -6,   -6,   -6,   -6,   -6,   -6,   -6,   -6,
+       -6,   -6,   -6,   -6,   -6,   -6,   -6,   -6,   -6,   -6,
+       -6,   -6,   -6,   -6,   -6,   -6,   -6,   -6,   -6,   -6,
+       -6,   -6,   -6,   -6,   -6,   -6,   -6,   -6,   -6,   -6,
+       -6
+    },
+
+    {
+        5,   -7,   36,   -7,   -7,   -7,   -7,   -7,   -7,   -7,
+       -7,   -7,   -7,   -7,   -7,   -7,   -7,   -7,   -7,   -7,
+       -7,   -7,   -7,   -7,   -7,   -7,   -7,   -7,   -7,   -7,
+       -7,   -7,   -7,   -7,   -7,   -7,   -7,   -7,   -7,   -7,
+       -7
+
+    },
+
+    {
+        5,   -8,   -8,   -8,   -8,   -8,   -8,   -8,   -8,   -8,
+       -8,   -8,   -8,   -8,   -8,   -8,   -8,   -8,   -8,   -8,
+       -8,   -8,   -8,   -8,   -8,   -8,   -8,   -8,   -8,   -8,
+       -8,   -8,   -8,   -8,   -8,   -8,   -8,   -8,   -8,   -8,
+       -8
+    },
+
+    {
+        5,   37,   37,   -9,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37
+
+    },
+
+    {
+        5,  -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,
+      -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,
+      -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,
+      -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,  -10,
+      -10
+    },
+
+    {
+        5,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
+      -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
+      -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
+      -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
+       38
+
+    },
+
+    {
+        5,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,   39,
+      -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,
+      -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,
+      -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,
+      -12
+    },
+
+    {
+        5,  -13,  -13,  -13,  -13,  -13,  -13,  -13,   40,   40,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -13,
+      -13
+
+    },
+
+    {
+        5,  -14,  -14,  -14,  -14,  -14,  -14,  -14,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -14,
+      -14
+    },
+
+    {
+        5,  -15,  -15,  -15,  -15,  -15,  -15,  -15,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   42,   41,   41,
+       41,   41,   41,   41,   43,   41,   41,   44,   41,  -15,
+      -15
+
+    },
+
+    {
+        5,  -16,  -16,  -16,  -16,  -16,  -16,  -16,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   45,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   46,  -16,
+      -16
+    },
+
+    {
+        5,  -17,  -17,  -17,  -17,  -17,  -17,  -17,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   47,   41,   48,   49,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -17,
+      -17
+
+    },
+
+    {
+        5,  -18,  -18,  -18,  -18,  -18,  -18,  -18,   41,   41,
+       41,   41,   41,   41,   50,   41,   41,   41,   51,   41,
+       41,   41,   41,   41,   41,   41,   41,   52,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -18,
+      -18
+    },
+
+    {
+        5,  -19,  -19,  -19,  -19,  -19,  -19,  -19,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   53,   41,   41,
+       54,   41,   41,   41,   41,   41,   41,   55,   41,  -19,
+      -19
+
+    },
+
+    {
+        5,  -20,  -20,  -20,  -20,  -20,  -20,  -20,   41,   41,
+       41,   41,   41,   41,   56,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   57,   41,
+       41,   58,   41,   41,   59,   41,   41,   41,   41,  -20,
+      -20
+    },
+
+    {
+        5,  -21,  -21,  -21,  -21,  -21,  -21,  -21,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   60,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -21,
+      -21
+
+    },
+
+    {
+        5,  -22,  -22,  -22,  -22,  -22,  -22,  -22,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   61,  -22,
+      -22
+    },
+
+    {
+        5,  -23,  -23,  -23,  -23,  -23,  -23,  -23,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   62,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -23,
+      -23
+
+    },
+
+    {
+        5,  -24,  -24,  -24,  -24,  -24,  -24,  -24,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   63,   41,   41,   41,   41,   41,   64,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -24,
+      -24
+    },
+
+    {
+        5,  -25,  -25,  -25,  -25,  -25,  -25,  -25,   41,   41,
+       41,   41,   41,   41,   65,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   66,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -25,
+      -25
+
+    },
+
+    {
+        5,  -26,  -26,  -26,  -26,  -26,  -26,  -26,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   67,
+       41,   68,   41,   41,   41,   41,   41,   41,   41,  -26,
+      -26
+    },
+
+    {
+        5,  -27,  -27,  -27,  -27,  -27,  -27,  -27,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   69,   41,   41,   41,   41,   41,   41,   41,  -27,
+      -27
+
+    },
+
+    {
+        5,  -28,  -28,  -28,  -28,  -28,  -28,  -28,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   70,   41,   41,   41,   41,  -28,
+      -28
+    },
+
+    {
+        5,  -29,  -29,  -29,  -29,  -29,  -29,  -29,   41,   41,
+       41,   41,   41,   41,   71,   41,   41,   41,   72,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   73,   41,
+       41,   41,   41,   74,   75,   41,   41,   41,   41,  -29,
+      -29
+
+    },
+
+    {
+        5,  -30,  -30,  -30,  -30,  -30,  -30,  -30,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   76,   41,   41,   41,   41,   41,   41,   41,  -30,
+      -30
+    },
+
+    {
+        5,  -31,  -31,  -31,  -31,  -31,  -31,  -31,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   77,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -31,
+      -31
+
+    },
+
+    {
+        5,  -32,  -32,  -32,  -32,  -32,  -32,  -32,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   78,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -32,
+      -32
+    },
+
+    {
+        5,  -33,  -33,  -33,  -33,  -33,   79,  -33,  -33,  -33,
+      -33,  -33,  -33,  -33,  -33,  -33,  -33,  -33,  -33,  -33,
+      -33,  -33,  -33,  -33,  -33,  -33,  -33,  -33,  -33,  -33,
+      -33,  -33,  -33,  -33,  -33,  -33,  -33,  -33,  -33,  -33,
+      -33
+
+    },
+
+    {
+        5,   80,   80,   80,   80,   80,  -34,   80,   80,   80,
+       80,   80,   80,   80,   80,   80,   80,   80,   80,   80,
+       80,   80,   80,   80,   80,   80,   80,   80,   80,   80,
+       80,   80,   80,   80,   80,   80,   80,   80,   80,   80,
+       80
+    },
+
+    {
+        5,   81,   81,   81,   81,   81,   82,   81,   81,   81,
+       81,   81,   81,   81,   81,   81,   81,   81,   81,   81,
+       81,   81,   81,   81,   81,   81,   81,   81,   81,   81,
+       81,   81,   81,   81,   81,   81,   81,   81,   81,   81,
+       83
+
+    },
+
+    {
+        5,  -36,   36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
+      -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
+      -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
+      -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
+      -36
+    },
+
+    {
+        5,   37,   37,  -37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,
+       37
+
+    },
+
+    {
+        5,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,
+      -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,
+      -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,
+      -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,
+      -38
+    },
+
+    {
+        5,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,
+      -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,
+      -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,
+      -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,  -39,
+      -39
+
+    },
+
+    {
+        5,  -40,  -40,  -40,  -40,  -40,  -40,  -40,   40,   40,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -40,
+      -40
+    },
+
+    {
+        5,  -41,  -41,  -41,  -41,  -41,  -41,  -41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -41,
+      -41
+
+    },
+
+    {
+        5,  -42,  -42,  -42,  -42,  -42,  -42,  -42,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   84,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -42,
+      -42
+    },
+
+    {
+        5,  -43,  -43,  -43,  -43,  -43,  -43,  -43,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   85,   41,   41,   41,   41,   41,  -43,
+      -43
+
+    },
+
+    {
+        5,  -44,  -44,  -44,  -44,  -44,  -44,  -44,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   86,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -44,
+      -44
+    },
+
+    {
+        5,  -45,  -45,  -45,  -45,  -45,  -45,  -45,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       87,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -45,
+      -45
+
+    },
+
+    {
+        5,  -46,  -46,  -46,  -46,  -46,  -46,  -46,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -46,
+      -46
+    },
+
+    {
+        5,  -47,  -47,  -47,  -47,  -47,  -47,  -47,   41,   41,
+       41,   41,   41,   41,   88,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -47,
+      -47
+
+    },
+
+    {
+        5,  -48,  -48,  -48,  -48,  -48,  -48,  -48,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   89,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -48,
+      -48
+    },
+
+    {
+        5,  -49,  -49,  -49,  -49,  -49,  -49,  -49,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   90,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -49,
+      -49
+
+    },
+
+    {
+        5,  -50,  -50,  -50,  -50,  -50,  -50,  -50,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   91,   41,   41,   41,   41,   41,  -50,
+      -50
+    },
+
+    {
+        5,  -51,  -51,  -51,  -51,  -51,  -51,  -51,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   92,   41,   41,   41,   41,   41,   41,  -51,
+      -51
+
+    },
+
+    {
+        5,  -52,  -52,  -52,  -52,  -52,  -52,  -52,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   93,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -52,
+      -52
+    },
+
+    {
+        5,  -53,  -53,  -53,  -53,  -53,  -53,  -53,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   94,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -53,
+      -53
+
+    },
+
+    {
+        5,  -54,  -54,  -54,  -54,  -54,  -54,  -54,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   95,   41,   41,   41,   41,  -54,
+      -54
+    },
+
+    {
+        5,  -55,  -55,  -55,  -55,  -55,  -55,  -55,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   96,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -55,
+      -55
+
+    },
+
+    {
+        5,  -56,  -56,  -56,  -56,  -56,  -56,  -56,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   97,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -56,
+      -56
+    },
+
+    {
+        5,  -57,  -57,  -57,  -57,  -57,  -57,  -57,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   98,   41,   41,   41,   41,   41,   41,   41,  -57,
+      -57
+
+    },
+
+    {
+        5,  -58,  -58,  -58,  -58,  -58,  -58,  -58,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   99,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -58,
+      -58
+    },
+
+    {
+        5,  -59,  -59,  -59,  -59,  -59,  -59,  -59,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,  100,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -59,
+      -59
+
+    },
+
+    {
+        5,  -60,  -60,  -60,  -60,  -60,  -60,  -60,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,  101,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -60,
+      -60
+    },
+
+    {
+        5,  -61,  -61,  -61,  -61,  -61,  -61,  -61,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  102,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -61,
+      -61
+
+    },
+
+    {
+        5,  -62,  -62,  -62,  -62,  -62,  -62,  -62,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  103,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -62,
+      -62
+    },
+
+    {
+        5,  -63,  -63,  -63,  -63,  -63,  -63,  -63,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  104,   41,   41,   41,   41,   41,   41,  -63,
+      -63
+
+    },
+
+    {
+        5,  -64,  -64,  -64,  -64,  -64,  -64,  -64,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+      105,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -64,
+      -64
+    },
+
+    {
+        5,  -65,  -65,  -65,  -65,  -65,  -65,  -65,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,  106,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -65,
+      -65
+
+    },
+
+    {
+        5,  -66,  -66,  -66,  -66,  -66,  -66,  -66,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  107,   41,   41,   41,   41,   41,  -66,
+      -66
+    },
+
+    {
+        5,  -67,  -67,  -67,  -67,  -67,  -67,  -67,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  108,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -67,
+      -67
+
+    },
+
+    {
+        5,  -68,  -68,  -68,  -68,  -68,  -68,  -68,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -68,
+      -68
+    },
+
+    {
+        5,  -69,  -69,  -69,  -69,  -69,  -69,  -69,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  109,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -69,
+      -69
+
+    },
+
+    {
+        5,  -70,  -70,  -70,  -70,  -70,  -70,  -70,   41,   41,
+       41,   41,   41,   41,  110,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -70,
+      -70
+    },
+
+    {
+        5,  -71,  -71,  -71,  -71,  -71,  -71,  -71,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  111,   41,   41,   41,   41,   41,  -71,
+      -71
+
+    },
+
+    {
+        5,  -72,  -72,  -72,  -72,  -72,  -72,  -72,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  112,   41,   41,   41,   41,   41,  -72,
+      -72
+    },
+
+    {
+        5,  -73,  -73,  -73,  -73,  -73,  -73,  -73,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  113,   41,   41,   41,   41,   41,   41,   41,  -73,
+      -73
+
+    },
+
+    {
+        5,  -74,  -74,  -74,  -74,  -74,  -74,  -74,   41,   41,
+       41,   41,   41,   41,  114,   41,   41,   41,  115,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -74,
+      -74
+    },
+
+    {
+        5,  -75,  -75,  -75,  -75,  -75,  -75,  -75,   41,   41,
+       41,   41,   41,   41,   41,  116,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -75,
+      -75
+
+    },
+
+    {
+        5,  -76,  -76,  -76,  -76,  -76,  -76,  -76,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,  117,   41,   41,   41,   41,  -76,
+      -76
+    },
+
+    {
+        5,  -77,  -77,  -77,  -77,  -77,  -77,  -77,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,  118,   41,   41,   41,   41,   41,
+       41,   41,  119,   41,   41,   41,   41,   41,   41,  -77,
+      -77
+
+    },
+
+    {
+        5,  -78,  -78,  -78,  -78,  -78,  -78,  -78,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  120,   41,   41,   41,   41,   41,   41,   41,  -78,
+      -78
+    },
+
+    {
+        5,  -79,  -79,  -79,  -79,  -79,  -79,  -79,  -79,  -79,
+      -79,  -79,  -79,  -79,  -79,  -79,  -79,  -79,  -79,  -79,
+      -79,  -79,  -79,  -79,  -79,  -79,  -79,  -79,  -79,  -79,
+      -79,  -79,  -79,  -79,  -79,  -79,  -79,  -79,  -79,  -79,
+      -79
+
+    },
+
+    {
+        5,   80,   80,   80,   80,   80,  -80,   80,   80,   80,
+       80,   80,   80,   80,   80,   80,   80,   80,   80,   80,
+       80,   80,   80,   80,   80,   80,   80,   80,   80,   80,
+       80,   80,   80,   80,   80,   80,   80,   80,   80,   80,
+       80
+    },
+
+    {
+        5,   81,   81,   81,   81,   81,  -81,   81,   81,   81,
+       81,   81,   81,   81,   81,   81,   81,   81,   81,   81,
+       81,   81,   81,   81,   81,   81,   81,   81,   81,   81,
+       81,   81,   81,   81,   81,   81,   81,   81,   81,   81,
+      -81
+
+    },
+
+    {
+        5,   81,   81,   81,   81,   81,   82,   81,   81,   81,
+       81,   81,   81,   81,   81,   81,   81,   81,   81,   81,
+       81,   81,   81,   81,   81,   81,   81,   81,   81,   81,
+       81,   81,   81,   81,   81,   81,   81,   81,   81,   81,
+       83
+    },
+
+    {
+        5,  -83,  -83,  -83,  -83,  -83,  -83,  -83,  -83,  -83,
+      -83,  -83,  -83,  -83,  -83,  -83,  -83,  -83,  -83,  -83,
+      -83,  -83,  -83,  -83,  -83,  -83,  -83,  -83,  -83,  -83,
+      -83,  -83,  -83,  -83,  -83,  -83,  -83,  -83,  -83,  -83,
+      -83
+
+    },
+
+    {
+        5,  -84,  -84,  -84,  -84,  -84,  -84,  -84,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -84,
+      -84
+    },
+
+    {
+        5,  -85,  -85,  -85,  -85,  -85,  -85,  -85,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  121,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -85,
+      -85
+
+    },
+
+    {
+        5,  -86,  -86,  -86,  -86,  -86,  -86,  -86,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  122,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -86,
+      -86
+    },
+
+    {
+        5,  -87,  -87,  -87,  -87,  -87,  -87,  -87,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  123,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -87,
+      -87
+
+    },
+
+    {
+        5,  -88,  -88,  -88,  -88,  -88,  -88,  -88,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,  124,   41,   41,   41,   41,  -88,
+      -88
+    },
+
+    {
+        5,  -89,  -89,  -89,  -89,  -89,  -89,  -89,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -89,
+      -89
+
+    },
+
+    {
+        5,  -90,  -90,  -90,  -90,  -90,  -90,  -90,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  125,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -90,
+      -90
+    },
+
+    {
+        5,  -91,  -91,  -91,  -91,  -91,  -91,  -91,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  126,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -91,
+      -91
+
+    },
+
+    {
+        5,  -92,  -92,  -92,  -92,  -92,  -92,  -92,   41,   41,
+       41,   41,   41,   41,   41,   41,  127,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -92,
+      -92
+    },
+
+    {
+        5,  -93,  -93,  -93,  -93,  -93,  -93,  -93,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -93,
+      -93
+
+    },
+
+    {
+        5,  -94,  -94,  -94,  -94,  -94,  -94,  -94,   41,   41,
+       41,   41,   41,  128,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -94,
+      -94
+    },
+
+    {
+        5,  -95,  -95,  -95,  -95,  -95,  -95,  -95,   41,   41,
+       41,   41,   41,   41,  129,   41,   41,   41,   41,   41,
+       41,   41,  130,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -95,
+      -95
+
+    },
+
+    {
+        5,  -96,  -96,  -96,  -96,  -96,  -96,  -96,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  131,   41,   41,   41,   41,   41,   41,  -96,
+      -96
+    },
+
+    {
+        5,  -97,  -97,  -97,  -97,  -97,  -97,  -97,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  132,   41,   41,   41,   41,   41,   41,  -97,
+      -97
+
+    },
+
+    {
+        5,  -98,  -98,  -98,  -98,  -98,  -98,  -98,   41,   41,
+       41,   41,   41,   41,  133,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,  134,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -98,
+      -98
+    },
+
+    {
+        5,  -99,  -99,  -99,  -99,  -99,  -99,  -99,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  135,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  -99,
+      -99
+
+    },
+
+    {
+        5, -100, -100, -100, -100, -100, -100, -100,   41,   41,
+       41,   41,   41,   41,   41,   41,  136,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -100,
+     -100
+    },
+
+    {
+        5, -101, -101, -101, -101, -101, -101, -101,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  137,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -101,
+     -101
+
+    },
+
+    {
+        5, -102, -102, -102, -102, -102, -102, -102,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  138,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -102,
+     -102
+    },
+
+    {
+        5, -103, -103, -103, -103, -103, -103, -103,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,  139,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -103,
+     -103
+
+    },
+
+    {
+        5, -104, -104, -104, -104, -104, -104, -104,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  140,   41,   41,   41,   41,   41, -104,
+     -104
+    },
+
+    {
+        5, -105, -105, -105, -105, -105, -105, -105,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  141,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -105,
+     -105
+
+    },
+
+    {
+        5, -106, -106, -106, -106, -106, -106, -106,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  142,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -106,
+     -106
+    },
+
+    {
+        5, -107, -107, -107, -107, -107, -107, -107,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -107,
+     -107
+
+    },
+
+    {
+        5, -108, -108, -108, -108, -108, -108, -108,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  143,   41,   41,   41,   41,   41,   41,   41, -108,
+     -108
+    },
+
+    {
+        5, -109, -109, -109, -109, -109, -109, -109,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,  144,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -109,
+     -109
+
+    },
+
+    {
+        5, -110, -110, -110, -110, -110, -110, -110,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,  145,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -110,
+     -110
+    },
+
+    {
+        5, -111, -111, -111, -111, -111, -111, -111,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  146,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -111,
+     -111
+
+    },
+
+    {
+        5, -112, -112, -112, -112, -112, -112, -112,   41,   41,
+       41,   41,   41,  147,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -112,
+     -112
+    },
+
+    {
+        5, -113, -113, -113, -113, -113, -113, -113,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  148,   41,   41,   41,   41,   41, -113,
+     -113
+
+    },
+
+    {
+        5, -114, -114, -114, -114, -114, -114, -114,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  149,   41,   41,   41,   41,   41, -114,
+     -114
+    },
+
+    {
+        5, -115, -115, -115, -115, -115, -115, -115,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  150,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -115,
+     -115
+
+    },
+
+    {
+        5, -116, -116, -116, -116, -116, -116, -116,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  151,   41,   41,   41,   41,   41,   41, -116,
+     -116
+    },
+
+    {
+        5, -117, -117, -117, -117, -117, -117, -117,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  152,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -117,
+     -117
+
+    },
+
+    {
+        5, -118, -118, -118, -118, -118, -118, -118,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,  153,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -118,
+     -118
+    },
+
+    {
+        5, -119, -119, -119, -119, -119, -119, -119,   41,   41,
+       41,   41,   41,   41,  154,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -119,
+     -119
+
+    },
+
+    {
+        5, -120, -120, -120, -120, -120, -120, -120,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  155,   41,   41,   41,   41,   41,   41, -120,
+     -120
+    },
+
+    {
+        5, -121, -121, -121, -121, -121, -121, -121,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  156,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -121,
+     -121
+
+    },
+
+    {
+        5, -122, -122, -122, -122, -122, -122, -122,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,  157,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -122,
+     -122
+    },
+
+    {
+        5, -123, -123, -123, -123, -123, -123, -123,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,  158,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -123,
+     -123
+
+    },
+
+    {
+        5, -124, -124, -124, -124, -124, -124, -124,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  159,   41,   41,   41,   41,   41,   41, -124,
+     -124
+    },
+
+    {
+        5, -125, -125, -125, -125, -125, -125, -125,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  160,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -125,
+     -125
+
+    },
+
+    {
+        5, -126, -126, -126, -126, -126, -126, -126,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -126,
+     -126
+    },
+
+    {
+        5, -127, -127, -127, -127, -127, -127, -127,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  161,   41,   41,   41,   41,   41,   41,   41, -127,
+     -127
+
+    },
+
+    {
+        5, -128, -128, -128, -128, -128, -128, -128,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  162,  163,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -128,
+     -128
+    },
+
+    {
+        5, -129, -129, -129, -129, -129, -129, -129,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,  164,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -129,
+     -129
+
+    },
+
+    {
+        5, -130, -130, -130, -130, -130, -130, -130,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,  165,   41,   41,   41, -130,
+     -130
+    },
+
+    {
+        5, -131, -131, -131, -131, -131, -131, -131,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  166,   41,   41,   41,   41,   41, -131,
+     -131
+
+    },
+
+    {
+        5, -132, -132, -132, -132, -132, -132, -132,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  167,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -132,
+     -132
+    },
+
+    {
+        5, -133, -133, -133, -133, -133, -133, -133,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,  168,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -133,
+     -133
+
+    },
+
+    {
+        5, -134, -134, -134, -134, -134, -134, -134,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,  169,   41,   41,   41,   41, -134,
+     -134
+    },
+
+    {
+        5, -135, -135, -135, -135, -135, -135, -135,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,  170,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -135,
+     -135
+
+    },
+
+    {
+        5, -136, -136, -136, -136, -136, -136, -136,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  171,   41,   41,   41,   41,   41, -136,
+     -136
+    },
+
+    {
+        5, -137, -137, -137, -137, -137, -137, -137,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  172,   41,   41,   41,   41,   41,   41,   41, -137,
+     -137
+
+    },
+
+    {
+        5, -138, -138, -138, -138, -138, -138, -138,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  173,   41,   41,   41,   41,   41, -138,
+     -138
+    },
+
+    {
+        5, -139, -139, -139, -139, -139, -139, -139,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  174,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -139,
+     -139
+
+    },
+
+    {
+        5, -140, -140, -140, -140, -140, -140, -140,   41,   41,
+       41,   41,   41,  175,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -140,
+     -140
+    },
+
+    {
+        5, -141, -141, -141, -141, -141, -141, -141,   41,   41,
+       41,   41,   41,   41,   41,   41,  176,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -141,
+     -141
+
+    },
+
+    {
+        5, -142, -142, -142, -142, -142, -142, -142,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -142,
+     -142
+    },
+
+    {
+        5, -143, -143, -143, -143, -143, -143, -143,   41,   41,
+       41,   41,   41,   41,  177,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -143,
+     -143
+
+    },
+
+    {
+        5, -144, -144, -144, -144, -144, -144, -144,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  178,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -144,
+     -144
+    },
+
+    {
+        5, -145, -145, -145, -145, -145, -145, -145,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  179,   41,   41,   41,   41,   41, -145,
+     -145
+
+    },
+
+    {
+        5, -146, -146, -146, -146, -146, -146, -146,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  180,   41,   41,   41,   41,   41,   41, -146,
+     -146
+    },
+
+    {
+        5, -147, -147, -147, -147, -147, -147, -147,   41,   41,
+       41,  181,   41,   41,   41,   41,   41,   41,   41,  182,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  183,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -147,
+     -147
+
+    },
+
+    {
+        5, -148, -148, -148, -148, -148, -148, -148,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  184,   41,   41,   41,   41,   41,   41, -148,
+     -148
+    },
+
+    {
+        5, -149, -149, -149, -149, -149, -149, -149,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,  185,   41,   41,   41,   41, -149,
+     -149
+
+    },
+
+    {
+        5, -150, -150, -150, -150, -150, -150, -150,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -150,
+     -150
+    },
+
+    {
+        5, -151, -151, -151, -151, -151, -151, -151,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  186,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -151,
+     -151
+
+    },
+
+    {
+        5, -152, -152, -152, -152, -152, -152, -152,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -152,
+     -152
+    },
+
+    {
+        5, -153, -153, -153, -153, -153, -153, -153,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  187,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -153,
+     -153
+
+    },
+
+    {
+        5, -154, -154, -154, -154, -154, -154, -154,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  188,   41,   41,   41,   41,   41, -154,
+     -154
+    },
+
+    {
+        5, -155, -155, -155, -155, -155, -155, -155,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  189,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -155,
+     -155
+
+    },
+
+    {
+        5, -156, -156, -156, -156, -156, -156, -156,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  190,   41,   41,   41,   41,   41,   41,   41, -156,
+     -156
+    },
+
+    {
+        5, -157, -157, -157, -157, -157, -157, -157,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  191,   41,   41,   41,   41,   41,   41, -157,
+     -157
+
+    },
+
+    {
+        5, -158, -158, -158, -158, -158, -158, -158,   41,   41,
+       41,   41,   41,  192,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -158,
+     -158
+    },
+
+    {
+        5, -159, -159, -159, -159, -159, -159, -159,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  193,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -159,
+     -159
+
+    },
+
+    {
+        5, -160, -160, -160, -160, -160, -160, -160,   41,   41,
+       41,   41,   41,   41,   41,   41,  194,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -160,
+     -160
+    },
+
+    {
+        5, -161, -161, -161, -161, -161, -161, -161,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  195,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -161,
+     -161
+
+    },
+
+    {
+        5, -162, -162, -162, -162, -162, -162, -162,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  196,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -162,
+     -162
+    },
+
+    {
+        5, -163, -163, -163, -163, -163, -163, -163,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  197,   41,   41,   41,   41,   41,   41,   41, -163,
+     -163
+
+    },
+
+    {
+        5, -164, -164, -164, -164, -164, -164, -164,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -164,
+     -164
+    },
+
+    {
+        5, -165, -165, -165, -165, -165, -165, -165,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -165,
+     -165
+
+    },
+
+    {
+        5, -166, -166, -166, -166, -166, -166, -166,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  198,   41,   41,   41,   41,   41,   41, -166,
+     -166
+    },
+
+    {
+        5, -167, -167, -167, -167, -167, -167, -167,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -167,
+     -167
+
+    },
+
+    {
+        5, -168, -168, -168, -168, -168, -168, -168,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,  199,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -168,
+     -168
+    },
+
+    {
+        5, -169, -169, -169, -169, -169, -169, -169,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,  200,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -169,
+     -169
+
+    },
+
+    {
+        5, -170, -170, -170, -170, -170, -170, -170,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  201, -170,
+     -170
+    },
+
+    {
+        5, -171, -171, -171, -171, -171, -171, -171,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  202,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -171,
+     -171
+
+    },
+
+    {
+        5, -172, -172, -172, -172, -172, -172, -172,   41,   41,
+       41,   41,   41,   41,  203,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -172,
+     -172
+    },
+
+    {
+        5, -173, -173, -173, -173, -173, -173, -173,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  204,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -173,
+     -173
+
+    },
+
+    {
+        5, -174, -174, -174, -174, -174, -174, -174,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  205,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -174,
+     -174
+    },
+
+    {
+        5, -175, -175, -175, -175, -175, -175, -175,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  206,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -175,
+     -175
+
+    },
+
+    {
+        5, -176, -176, -176, -176, -176, -176, -176,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -176,
+     -176
+    },
+
+    {
+        5, -177, -177, -177, -177, -177, -177, -177,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  207,   41,   41,   41,   41,   41, -177,
+     -177
+
+    },
+
+    {
+        5, -178, -178, -178, -178, -178, -178, -178,   41,   41,
+       41,   41,   41,   41,   41,   41,  208,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -178,
+     -178
+    },
+
+    {
+        5, -179, -179, -179, -179, -179, -179, -179,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  209,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -179,
+     -179
+
+    },
+
+    {
+        5, -180, -180, -180, -180, -180, -180, -180,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  210,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -180,
+     -180
+    },
+
+    {
+        5, -181, -181, -181, -181, -181, -181, -181,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  211,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -181,
+     -181
+
+    },
+
+    {
+        5, -182, -182, -182, -182, -182, -182, -182,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,  212,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -182,
+     -182
+    },
+
+    {
+        5, -183, -183, -183, -183, -183, -183, -183,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  213,   41,   41,   41,   41,   41,   41,   41, -183,
+     -183
+
+    },
+
+    {
+        5, -184, -184, -184, -184, -184, -184, -184,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -184,
+     -184
+    },
+
+    {
+        5, -185, -185, -185, -185, -185, -185, -185,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  214,   41,   41,   41,   41,   41,   41, -185,
+     -185
+
+    },
+
+    {
+        5, -186, -186, -186, -186, -186, -186, -186,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  215,   41,   41,   41,   41,   41,   41,   41, -186,
+     -186
+    },
+
+    {
+        5, -187, -187, -187, -187, -187, -187, -187,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,  216,   41,   41, -187,
+     -187
+
+    },
+
+    {
+        5, -188, -188, -188, -188, -188, -188, -188,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  217,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -188,
+     -188
+    },
+
+    {
+        5, -189, -189, -189, -189, -189, -189, -189,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  218,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -189,
+     -189
+
+    },
+
+    {
+        5, -190, -190, -190, -190, -190, -190, -190,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -190,
+     -190
+    },
+
+    {
+        5, -191, -191, -191, -191, -191, -191, -191,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -191,
+     -191
+
+    },
+
+    {
+        5, -192, -192, -192, -192, -192, -192, -192,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  219,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -192,
+     -192
+    },
+
+    {
+        5, -193, -193, -193, -193, -193, -193, -193,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -193,
+     -193
+
+    },
+
+    {
+        5, -194, -194, -194, -194, -194, -194, -194,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  220,   41,   41,   41,   41,   41, -194,
+     -194
+    },
+
+    {
+        5, -195, -195, -195, -195, -195, -195, -195,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  221,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -195,
+     -195
+
+    },
+
+    {
+        5, -196, -196, -196, -196, -196, -196, -196,   41,   41,
+       41,   41,   41,  222,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -196,
+     -196
+    },
+
+    {
+        5, -197, -197, -197, -197, -197, -197, -197,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  223,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -197,
+     -197
+
+    },
+
+    {
+        5, -198, -198, -198, -198, -198, -198, -198,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -198,
+     -198
+    },
+
+    {
+        5, -199, -199, -199, -199, -199, -199, -199,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -199,
+     -199
+
+    },
+
+    {
+        5, -200, -200, -200, -200, -200, -200, -200,   41,   41,
+       41,   41,   41,   41,  224,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -200,
+     -200
+    },
+
+    {
+        5, -201, -201, -201, -201, -201, -201, -201,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -201,
+     -201
+
+    },
+
+    {
+        5, -202, -202, -202, -202, -202, -202, -202,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  225,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -202,
+     -202
+    },
+
+    {
+        5, -203, -203, -203, -203, -203, -203, -203,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  226,   41,   41,   41,   41,   41, -203,
+     -203
+
+    },
+
+    {
+        5, -204, -204, -204, -204, -204, -204, -204,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  227,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -204,
+     -204
+    },
+
+    {
+        5, -205, -205, -205, -205, -205, -205, -205,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,  228,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  229,   41,   41,   41,   41,   41,   41, -205,
+     -205
+
+    },
+
+    {
+        5, -206, -206, -206, -206, -206, -206, -206,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  230,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -206,
+     -206
+    },
+
+    {
+        5, -207, -207, -207, -207, -207, -207, -207,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  231,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -207,
+     -207
+
+    },
+
+    {
+        5, -208, -208, -208, -208, -208, -208, -208,   41,   41,
+       41,   41,   41,   41,  232,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -208,
+     -208
+    },
+
+    {
+        5, -209, -209, -209, -209, -209, -209, -209,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  233,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -209,
+     -209
+
+    },
+
+    {
+        5, -210, -210, -210, -210, -210, -210, -210,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  234,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -210,
+     -210
+    },
+
+    {
+        5, -211, -211, -211, -211, -211, -211, -211,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,  235,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -211,
+     -211
+
+    },
+
+    {
+        5, -212, -212, -212, -212, -212, -212, -212,   41,   41,
+       41,   41,   41,   41,  236,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -212,
+     -212
+    },
+
+    {
+        5, -213, -213, -213, -213, -213, -213, -213,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  237,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -213,
+     -213
+
+    },
+
+    {
+        5, -214, -214, -214, -214, -214, -214, -214,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -214,
+     -214
+    },
+
+    {
+        5, -215, -215, -215, -215, -215, -215, -215,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  238,   41,   41,   41,   41,   41, -215,
+     -215
+
+    },
+
+    {
+        5, -216, -216, -216, -216, -216, -216, -216,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,  239,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -216,
+     -216
+    },
+
+    {
+        5, -217, -217, -217, -217, -217, -217, -217,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  240,   41,   41,   41,   41,   41,   41, -217,
+     -217
+
+    },
+
+    {
+        5, -218, -218, -218, -218, -218, -218, -218,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,  241,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -218,
+     -218
+    },
+
+    {
+        5, -219, -219, -219, -219, -219, -219, -219,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  242,   41,   41,   41,   41,   41,   41,   41, -219,
+     -219
+
+    },
+
+    {
+        5, -220, -220, -220, -220, -220, -220, -220,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,  243,   41,   41,   41,   41, -220,
+     -220
+    },
+
+    {
+        5, -221, -221, -221, -221, -221, -221, -221,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  244,   41,   41,   41,   41,   41, -221,
+     -221
+
+    },
+
+    {
+        5, -222, -222, -222, -222, -222, -222, -222,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,  245,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -222,
+     -222
+    },
+
+    {
+        5, -223, -223, -223, -223, -223, -223, -223,   41,   41,
+       41,   41,   41,   41,   41,  246,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -223,
+     -223
+
+    },
+
+    {
+        5, -224, -224, -224, -224, -224, -224, -224,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -224,
+     -224
+    },
+
+    {
+        5, -225, -225, -225, -225, -225, -225, -225,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,  247,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -225,
+     -225
+
+    },
+
+    {
+        5, -226, -226, -226, -226, -226, -226, -226,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  248,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -226,
+     -226
+    },
+
+    {
+        5, -227, -227, -227, -227, -227, -227, -227,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  249,   41,   41,   41,   41,   41,   41, -227,
+     -227
+
+    },
+
+    {
+        5, -228, -228, -228, -228, -228, -228, -228,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -228,
+     -228
+    },
+
+    {
+        5, -229, -229, -229, -229, -229, -229, -229,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -229,
+     -229
+
+    },
+
+    {
+        5, -230, -230, -230, -230, -230, -230, -230,   41,   41,
+       41,   41,   41,  250,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -230,
+     -230
+    },
+
+    {
+        5, -231, -231, -231, -231, -231, -231, -231,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  251,   41,   41,   41,   41,   41,   41,   41, -231,
+     -231
+
+    },
+
+    {
+        5, -232, -232, -232, -232, -232, -232, -232,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  252,   41,   41,   41,   41,   41, -232,
+     -232
+    },
+
+    {
+        5, -233, -233, -233, -233, -233, -233, -233,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  253,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -233,
+     -233
+
+    },
+
+    {
+        5, -234, -234, -234, -234, -234, -234, -234,   41,   41,
+       41,   41,   41,   41,  254,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -234,
+     -234
+    },
+
+    {
+        5, -235, -235, -235, -235, -235, -235, -235,   41,   41,
+       41,   41,  255,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -235,
+     -235
+
+    },
+
+    {
+        5, -236, -236, -236, -236, -236, -236, -236,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+      256,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -236,
+     -236
+    },
+
+    {
+        5, -237, -237, -237, -237, -237, -237, -237,   41,   41,
+       41,   41,   41,   41,   41,   41,  257,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -237,
+     -237
+
+    },
+
+    {
+        5, -238, -238, -238, -238, -238, -238, -238,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -238,
+     -238
+    },
+
+    {
+        5, -239, -239, -239, -239, -239, -239, -239,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -239,
+     -239
+
+    },
+
+    {
+        5, -240, -240, -240, -240, -240, -240, -240,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  258,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -240,
+     -240
+    },
+
+    {
+        5, -241, -241, -241, -241, -241, -241, -241,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -241,
+     -241
+
+    },
+
+    {
+        5, -242, -242, -242, -242, -242, -242, -242,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  259,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -242,
+     -242
+    },
+
+    {
+        5, -243, -243, -243, -243, -243, -243, -243,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  260,   41,   41,   41,   41,   41,   41,   41, -243,
+     -243
+
+    },
+
+    {
+        5, -244, -244, -244, -244, -244, -244, -244,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  261,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -244,
+     -244
+    },
+
+    {
+        5, -245, -245, -245, -245, -245, -245, -245,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  262,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -245,
+     -245
+
+    },
+
+    {
+        5, -246, -246, -246, -246, -246, -246, -246,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,  263,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -246,
+     -246
+    },
+
+    {
+        5, -247, -247, -247, -247, -247, -247, -247,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  264,   41,   41,   41,   41,   41,   41, -247,
+     -247
+
+    },
+
+    {
+        5, -248, -248, -248, -248, -248, -248, -248,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,  265,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -248,
+     -248
+    },
+
+    {
+        5, -249, -249, -249, -249, -249, -249, -249,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  266,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -249,
+     -249
+
+    },
+
+    {
+        5, -250, -250, -250, -250, -250, -250, -250,   41,   41,
+       41,   41,   41,   41,   41,   41,  267,  268,   41,  269,
+      270,   41,   41,   41,   41,   41,   41,   41,   41,  271,
+       41,   41,  272,  273,   41,   41,   41,   41,   41, -250,
+     -250
+    },
+
+    {
+        5, -251, -251, -251, -251, -251, -251, -251,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  274,   41,   41,   41,   41,   41,   41, -251,
+     -251
+
+    },
+
+    {
+        5, -252, -252, -252, -252, -252, -252, -252,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  275,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -252,
+     -252
+    },
+
+    {
+        5, -253, -253, -253, -253, -253, -253, -253,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  276,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -253,
+     -253
+
+    },
+
+    {
+        5, -254, -254, -254, -254, -254, -254, -254,   41,   41,
+       41,   41,   41,   41,   41,  277,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -254,
+     -254
+    },
+
+    {
+        5, -255, -255, -255, -255, -255, -255, -255,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  278,   41,   41,   41,   41,   41,   41,   41, -255,
+     -255
+
+    },
+
+    {
+        5, -256, -256, -256, -256, -256, -256, -256,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -256,
+     -256
+    },
+
+    {
+        5, -257, -257, -257, -257, -257, -257, -257,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  279,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -257,
+     -257
+
+    },
+
+    {
+        5, -258, -258, -258, -258, -258, -258, -258,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  280,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -258,
+     -258
+    },
+
+    {
+        5, -259, -259, -259, -259, -259, -259, -259,   41,   41,
+       41,   41,   41,   41,   41,  281,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -259,
+     -259
+
+    },
+
+    {
+        5, -260, -260, -260, -260, -260, -260, -260,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  282,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -260,
+     -260
+    },
+
+    {
+        5, -261, -261, -261, -261, -261, -261, -261,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  283,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -261,
+     -261
+
+    },
+
+    {
+        5, -262, -262, -262, -262, -262, -262, -262,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  284,   41,   41,   41,   41,   41,   41, -262,
+     -262
+    },
+
+    {
+        5, -263, -263, -263, -263, -263, -263, -263,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  285,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -263,
+     -263
+
+    },
+
+    {
+        5, -264, -264, -264, -264, -264, -264, -264,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -264,
+     -264
+    },
+
+    {
+        5, -265, -265, -265, -265, -265, -265, -265,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -265,
+     -265
+
+    },
+
+    {
+        5, -266, -266, -266, -266, -266, -266, -266,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  286,   41,   41,   41,   41,   41,   41, -266,
+     -266
+    },
+
+    {
+        5, -267, -267, -267, -267, -267, -267, -267,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,  287,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -267,
+     -267
+
+    },
+
+    {
+        5, -268, -268, -268, -268, -268, -268, -268,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  288,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -268,
+     -268
+    },
+
+    {
+        5, -269, -269, -269, -269, -269, -269, -269,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  289,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -269,
+     -269
+
+    },
+
+    {
+        5, -270, -270, -270, -270, -270, -270, -270,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  290,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -270,
+     -270
+    },
+
+    {
+        5, -271, -271, -271, -271, -271, -271, -271,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  291,   41,   41,   41,   41,   41,   41,   41, -271,
+     -271
+
+    },
+
+    {
+        5, -272, -272, -272, -272, -272, -272, -272,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  292,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  293, -272,
+     -272
+    },
+
+    {
+        5, -273, -273, -273, -273, -273, -273, -273,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  294,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -273,
+     -273
+
+    },
+
+    {
+        5, -274, -274, -274, -274, -274, -274, -274,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -274,
+     -274
+    },
+
+    {
+        5, -275, -275, -275, -275, -275, -275, -275,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  295,   41,   41,   41,   41,   41,   41, -275,
+     -275
+
+    },
+
+    {
+        5, -276, -276, -276, -276, -276, -276, -276,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  296,   41,   41,   41,   41,   41,   41,   41, -276,
+     -276
+    },
+
+    {
+        5, -277, -277, -277, -277, -277, -277, -277,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,  297,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -277,
+     -277
+
+    },
+
+    {
+        5, -278, -278, -278, -278, -278, -278, -278,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  298,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -278,
+     -278
+    },
+
+    {
+        5, -279, -279, -279, -279, -279, -279, -279,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,  299,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -279,
+     -279
+
+    },
+
+    {
+        5, -280, -280, -280, -280, -280, -280, -280,   41,   41,
+       41,   41,   41,   41,  300,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -280,
+     -280
+    },
+
+    {
+        5, -281, -281, -281, -281, -281, -281, -281,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,  301,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -281,
+     -281
+
+    },
+
+    {
+        5, -282, -282, -282, -282, -282, -282, -282,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  302,   41,   41,   41,   41,   41,   41, -282,
+     -282
+    },
+
+    {
+        5, -283, -283, -283, -283, -283, -283, -283,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,  303,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -283,
+     -283
+
+    },
+
+    {
+        5, -284, -284, -284, -284, -284, -284, -284,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  304,   41,   41,   41,   41,   41, -284,
+     -284
+    },
+
+    {
+        5, -285, -285, -285, -285, -285, -285, -285,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,  305,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -285,
+     -285
+
+    },
+
+    {
+        5, -286, -286, -286, -286, -286, -286, -286,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -286,
+     -286
+    },
+
+    {
+        5, -287, -287, -287, -287, -287, -287, -287,   41,   41,
+       41,   41,   41,   41,  306,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -287,
+     -287
+
+    },
+
+    {
+        5, -288, -288, -288, -288, -288, -288, -288,   41,   41,
+       41,   41,   41,   41,   41,   41,  307,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  308,   41,   41,   41,   41,   41,   41, -288,
+     -288
+    },
+
+    {
+        5, -289, -289, -289, -289, -289, -289, -289,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  309,   41,   41,   41,   41,   41,   41,   41, -289,
+     -289
+
+    },
+
+    {
+        5, -290, -290, -290, -290, -290, -290, -290,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,  310,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -290,
+     -290
+    },
+
+    {
+        5, -291, -291, -291, -291, -291, -291, -291,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  311,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -291,
+     -291
+
+    },
+
+    {
+        5, -292, -292, -292, -292, -292, -292, -292,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  312,   41,   41,   41,   41,   41, -292,
+     -292
+    },
+
+    {
+        5, -293, -293, -293, -293, -293, -293, -293,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,  313,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -293,
+     -293
+
+    },
+
+    {
+        5, -294, -294, -294, -294, -294, -294, -294,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  314,   41,   41,   41,   41,   41,   41,   41, -294,
+     -294
+    },
+
+    {
+        5, -295, -295, -295, -295, -295, -295, -295,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -295,
+     -295
+
+    },
+
+    {
+        5, -296, -296, -296, -296, -296, -296, -296,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  315,   41,   41,   41,   41,   41,   41, -296,
+     -296
+    },
+
+    {
+        5, -297, -297, -297, -297, -297, -297, -297,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  316,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -297,
+     -297
+
+    },
+
+    {
+        5, -298, -298, -298, -298, -298, -298, -298,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,  317,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -298,
+     -298
+    },
+
+    {
+        5, -299, -299, -299, -299, -299, -299, -299,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  318,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -299,
+     -299
+
+    },
+
+    {
+        5, -300, -300, -300, -300, -300, -300, -300,   41,   41,
+       41,   41,   41,   41,   41,  319,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -300,
+     -300
+    },
+
+    {
+        5, -301, -301, -301, -301, -301, -301, -301,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  320,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -301,
+     -301
+
+    },
+
+    {
+        5, -302, -302, -302, -302, -302, -302, -302,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -302,
+     -302
+    },
+
+    {
+        5, -303, -303, -303, -303, -303, -303, -303,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -303,
+     -303
+
+    },
+
+    {
+        5, -304, -304, -304, -304, -304, -304, -304,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -304,
+     -304
+    },
+
+    {
+        5, -305, -305, -305, -305, -305, -305, -305,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -305,
+     -305
+
+    },
+
+    {
+        5, -306, -306, -306, -306, -306, -306, -306,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,  321,   41,   41,   41,   41, -306,
+     -306
+    },
+
+    {
+        5, -307, -307, -307, -307, -307, -307, -307,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,  322,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -307,
+     -307
+
+    },
+
+    {
+        5, -308, -308, -308, -308, -308, -308, -308,   41,   41,
+       41,   41,   41,   41,   41,   41,  323,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -308,
+     -308
+    },
+
+    {
+        5, -309, -309, -309, -309, -309, -309, -309,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,  324,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -309,
+     -309
+
+    },
+
+    {
+        5, -310, -310, -310, -310, -310, -310, -310,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  325,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -310,
+     -310
+    },
+
+    {
+        5, -311, -311, -311, -311, -311, -311, -311,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  326,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -311,
+     -311
+
+    },
+
+    {
+        5, -312, -312, -312, -312, -312, -312, -312,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  327,   41,   41,   41,   41,   41, -312,
+     -312
+    },
+
+    {
+        5, -313, -313, -313, -313, -313, -313, -313,   41,   41,
+       41,   41,   41,   41,   41,  328,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -313,
+     -313
+
+    },
+
+    {
+        5, -314, -314, -314, -314, -314, -314, -314,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,  329,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -314,
+     -314
+    },
+
+    {
+        5, -315, -315, -315, -315, -315, -315, -315,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -315,
+     -315
+
+    },
+
+    {
+        5, -316, -316, -316, -316, -316, -316, -316,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -316,
+     -316
+    },
+
+    {
+        5, -317, -317, -317, -317, -317, -317, -317,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -317,
+     -317
+
+    },
+
+    {
+        5, -318, -318, -318, -318, -318, -318, -318,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,  330,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -318,
+     -318
+    },
+
+    {
+        5, -319, -319, -319, -319, -319, -319, -319,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,  331,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -319,
+     -319
+
+    },
+
+    {
+        5, -320, -320, -320, -320, -320, -320, -320,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,  332,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -320,
+     -320
+    },
+
+    {
+        5, -321, -321, -321, -321, -321, -321, -321,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  333,   41,   41,   41,   41,   41,   41, -321,
+     -321
+
+    },
+
+    {
+        5, -322, -322, -322, -322, -322, -322, -322,   41,   41,
+       41,   41,   41,   41,  334,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -322,
+     -322
+    },
+
+    {
+        5, -323, -323, -323, -323, -323, -323, -323,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  335,   41,   41,   41,   41,   41,   41,   41, -323,
+     -323
+
+    },
+
+    {
+        5, -324, -324, -324, -324, -324, -324, -324,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,  336,   41,   41,   41,   41, -324,
+     -324
+    },
+
+    {
+        5, -325, -325, -325, -325, -325, -325, -325,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  337,   41,   41,   41,   41,   41,   41,   41, -325,
+     -325
+
+    },
+
+    {
+        5, -326, -326, -326, -326, -326, -326, -326,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  338,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -326,
+     -326
+    },
+
+    {
+        5, -327, -327, -327, -327, -327, -327, -327,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  339,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -327,
+     -327
+
+    },
+
+    {
+        5, -328, -328, -328, -328, -328, -328, -328,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  340,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -328,
+     -328
+    },
+
+    {
+        5, -329, -329, -329, -329, -329, -329, -329,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  341,   41,   41,   41,   41,   41,   41, -329,
+     -329
+
+    },
+
+    {
+        5, -330, -330, -330, -330, -330, -330, -330,   41,   41,
+       41,   41,   41,   41,   41,   41,  342,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -330,
+     -330
+    },
+
+    {
+        5, -331, -331, -331, -331, -331, -331, -331,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  343,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -331,
+     -331
+
+    },
+
+    {
+        5, -332, -332, -332, -332, -332, -332, -332,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -332,
+     -332
+    },
+
+    {
+        5, -333, -333, -333, -333, -333, -333, -333,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  344,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -333,
+     -333
+
+    },
+
+    {
+        5, -334, -334, -334, -334, -334, -334, -334,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,  345,   41,   41,   41,   41,   41,   41,   41, -334,
+     -334
+    },
+
+    {
+        5, -335, -335, -335, -335, -335, -335, -335,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  346,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -335,
+     -335
+
+    },
+
+    {
+        5, -336, -336, -336, -336, -336, -336, -336,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,  347,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -336,
+     -336
+    },
+
+    {
+        5, -337, -337, -337, -337, -337, -337, -337,   41,   41,
+       41,   41,   41,   41,  348,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -337,
+     -337
+
+    },
+
+    {
+        5, -338, -338, -338, -338, -338, -338, -338,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -338,
+     -338
+    },
+
+    {
+        5, -339, -339, -339, -339, -339, -339, -339,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,  349,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -339,
+     -339
+
+    },
+
+    {
+        5, -340, -340, -340, -340, -340, -340, -340,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,  350,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -340,
+     -340
+    },
+
+    {
+        5, -341, -341, -341, -341, -341, -341, -341,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -341,
+     -341
+
+    },
+
+    {
+        5, -342, -342, -342, -342, -342, -342, -342,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  351,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -342,
+     -342
+    },
+
+    {
+        5, -343, -343, -343, -343, -343, -343, -343,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -343,
+     -343
+
+    },
+
+    {
+        5, -344, -344, -344, -344, -344, -344, -344,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  352,   41,   41,   41,   41,   41,   41, -344,
+     -344
+    },
+
+    {
+        5, -345, -345, -345, -345, -345, -345, -345,   41,   41,
+       41,   41,   41,   41,  353,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -345,
+     -345
+
+    },
+
+    {
+        5, -346, -346, -346, -346, -346, -346, -346,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,  354,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -346,
+     -346
+    },
+
+    {
+        5, -347, -347, -347, -347, -347, -347, -347,   41,   41,
+       41,   41,   41,   41,  355,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -347,
+     -347
+
+    },
+
+    {
+        5, -348, -348, -348, -348, -348, -348, -348,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,  356,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -348,
+     -348
+    },
+
+    {
+        5, -349, -349, -349, -349, -349, -349, -349,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+      357,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -349,
+     -349
+
+    },
+
+    {
+        5, -350, -350, -350, -350, -350, -350, -350,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  358,   41,   41,   41,   41,   41,   41, -350,
+     -350
+    },
+
+    {
+        5, -351, -351, -351, -351, -351, -351, -351,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -351,
+     -351
+
+    },
+
+    {
+        5, -352, -352, -352, -352, -352, -352, -352,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -352,
+     -352
+    },
+
+    {
+        5, -353, -353, -353, -353, -353, -353, -353,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  359,   41,   41,   41,   41,   41, -353,
+     -353
+
+    },
+
+    {
+        5, -354, -354, -354, -354, -354, -354, -354,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  360,   41,   41,   41,   41,   41, -354,
+     -354
+    },
+
+    {
+        5, -355, -355, -355, -355, -355, -355, -355,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  361,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -355,
+     -355
+
+    },
+
+    {
+        5, -356, -356, -356, -356, -356, -356, -356,   41,   41,
+       41,   41,   41,  362,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -356,
+     -356
+    },
+
+    {
+        5, -357, -357, -357, -357, -357, -357, -357,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  363,   41,   41,   41,   41,   41,   41, -357,
+     -357
+
+    },
+
+    {
+        5, -358, -358, -358, -358, -358, -358, -358,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -358,
+     -358
+    },
+
+    {
+        5, -359, -359, -359, -359, -359, -359, -359,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  364,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -359,
+     -359
+
+    },
+
+    {
+        5, -360, -360, -360, -360, -360, -360, -360,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  365,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -360,
+     -360
+    },
+
+    {
+        5, -361, -361, -361, -361, -361, -361, -361,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -361,
+     -361
+
+    },
+
+    {
+        5, -362, -362, -362, -362, -362, -362, -362,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  366,   41,   41,   41,   41,   41,   41, -362,
+     -362
+    },
+
+    {
+        5, -363, -363, -363, -363, -363, -363, -363,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -363,
+     -363
+
+    },
+
+    {
+        5, -364, -364, -364, -364, -364, -364, -364,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  367,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -364,
+     -364
+    },
+
+    {
+        5, -365, -365, -365, -365, -365, -365, -365,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  368,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -365,
+     -365
+
+    },
+
+    {
+        5, -366, -366, -366, -366, -366, -366, -366,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,  369,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -366,
+     -366
+    },
+
+    {
+        5, -367, -367, -367, -367, -367, -367, -367,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,  370,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -367,
+     -367
+
+    },
+
+    {
+        5, -368, -368, -368, -368, -368, -368, -368,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,  371,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -368,
+     -368
+    },
+
+    {
+        5, -369, -369, -369, -369, -369, -369, -369,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  372,   41,   41,   41,   41,   41, -369,
+     -369
+
+    },
+
+    {
+        5, -370, -370, -370, -370, -370, -370, -370,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  373,   41,   41,   41,   41,   41,   41, -370,
+     -370
+    },
+
+    {
+        5, -371, -371, -371, -371, -371, -371, -371,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  374,   41,   41,   41,   41,   41,   41, -371,
+     -371
+
+    },
+
+    {
+        5, -372, -372, -372, -372, -372, -372, -372,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,  375,   41,   41,   41,   41,   41, -372,
+     -372
+    },
+
+    {
+        5, -373, -373, -373, -373, -373, -373, -373,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -373,
+     -373
+
+    },
+
+    {
+        5, -374, -374, -374, -374, -374, -374, -374,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -374,
+     -374
+    },
+
+    {
+        5, -375, -375, -375, -375, -375, -375, -375,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  376,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -375,
+     -375
+
+    },
+
+    {
+        5, -376, -376, -376, -376, -376, -376, -376,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,  377,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -376,
+     -376
+    },
+
+    {
+        5, -377, -377, -377, -377, -377, -377, -377,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+      378,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -377,
+     -377
+
+    },
+
+    {
+        5, -378, -378, -378, -378, -378, -378, -378,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,  379,   41,   41,   41,   41,   41,   41, -378,
+     -378
+    },
+
+    {
+        5, -379, -379, -379, -379, -379, -379, -379,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,   41,   41,   41, -379,
+     -379
+
+    },
+
+    } ;
+
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	yytext_ptr = yy_bp; \
+	yytext_ptr -= yy_more_len; \
+	yyleng = (int) (yy_cp - yytext_ptr); \
+	yy_hold_char = *yy_cp; \
+	*yy_cp = '\0'; \
+	yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 69
+#define YY_END_OF_BUFFER 70
+static yyconst short int yy_accept[380] =
+    {   0,
+        0,    0,    0,    0,   70,   68,   65,   66,   57,   67,
+       68,   67,   63,   64,   64,   64,   64,   64,   64,   64,
+       64,   64,   64,   64,   64,   64,   64,   64,   64,   64,
+       64,   64,   68,   60,   61,   65,   57,   59,   56,   63,
+       64,   64,   64,   64,   64,    5,   64,   64,   64,   64,
+       64,   64,   64,   64,   64,   64,   64,   64,   64,   64,
+       64,   64,   64,   64,   64,   64,   64,   39,   64,   64,
+       64,   64,   64,   64,   64,   64,   64,   64,   58,   60,
+       61,   61,   62,    1,   64,   64,   64,   64,    7,   64,
+       64,   64,   11,   64,   64,   64,   64,   64,   64,   64,
+
+       64,   64,   64,   64,   64,   64,   37,   64,   64,   64,
+       64,   64,   64,   64,   64,   64,   64,   64,   64,   64,
+       64,   64,   64,   64,   64,    9,   64,   64,   64,   64,
+       64,   64,   64,   64,   64,   64,   64,   64,   64,   64,
+       64,   36,   64,   64,   64,   64,   64,   47,   64,   50,
+       64,   52,   64,   64,   64,   64,   64,   64,   64,   64,
+       64,   64,   64,   14,   15,   64,   17,   64,   64,   64,
+       64,   64,   64,   64,   64,   35,   64,   64,   64,   64,
+       64,   64,   64,   48,   64,   64,   64,   64,   64,    2,
+        3,   64,    6,   64,   64,   64,   64,   16,   18,   64,
+
+       20,   64,   64,   64,   64,   64,   64,   64,   64,   64,
+       64,   64,   64,   49,   64,   64,   64,   64,   64,   64,
+       64,   64,   64,   19,   64,   64,   64,   24,   25,   64,
+       64,   64,   64,   64,   64,   64,   64,   51,   53,   64,
+       55,   64,   64,   64,   64,   64,   64,   64,   64,   64,
+       64,   64,   64,   64,   64,   45,   64,   64,   64,   64,
+       64,   64,   64,   21,   22,   64,   64,   64,   64,   64,
+       64,   64,   64,   38,   40,   64,   64,   64,   64,   64,
+       64,   64,   64,   64,   64,   23,   64,   64,   64,   64,
+       64,   64,   64,   64,   41,   64,   64,   64,   64,   64,
+
+       64,    8,   10,   12,   13,   64,   64,   64,   64,   64,
+       64,   64,   64,   64,   42,   43,   44,   64,   64,   64,
+       64,   64,   64,   64,   64,   64,   64,   64,   64,   64,
+       64,    4,   64,   64,   64,   64,   64,   31,   64,   64,
+       34,   64,   54,   64,   64,   64,   64,   64,   64,   64,
+       46,   26,   64,   64,   64,   64,   64,   33,   64,   64,
+       29,   64,   32,   64,   64,   64,   64,   64,   64,   64,
+       64,   64,   27,   28,   64,   64,   64,   64,   30
+    } ;
+
+static yyconst int yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    2,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    1,    1,    1,    1,    4,    1,    1,    5,
+        5,    6,    1,    5,    7,    5,    1,    8,    9,    8,
+        8,    8,    8,    8,    8,    8,    8,    5,    1,    1,
+        1,    1,    1,    1,   10,   10,   10,   11,   10,   10,
+       10,   10,   10,   10,   10,   10,   10,   10,   10,   12,
+       10,   10,   10,   10,   10,   10,   10,   10,   10,   10,
+        5,    1,    5,    1,   13,    1,   14,   15,   16,   17,
+
+       18,   19,   20,   21,   22,   23,   24,   25,   26,   27,
+       28,   29,   30,   31,   32,   33,   34,   35,   36,   37,
+       38,   10,   39,    1,   40,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+static int yy_more_flag = 0;
+static int yy_more_len = 0;
+#define yymore() (yy_more_flag = 1)
+#define YY_MORE_ADJ yy_more_len
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "dfgscanner.l"
+#define INITIAL 0
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                 SCANNER FOR DFG SYNTAX                 * */
+/* *                                                        * */
+/* *  $Module:   DFG                                        * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1997, 1998, 1999, 2000, 2001            * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+/* $RCSfile$ */
+#line 49 "dfgscanner.l"
+
+#include <ctype.h>    /* for isprint */
+#include <errno.h>
+#include "misc.h"
+#include "memory.h"
+#include "symbol.h"
+#include "term.h"
+#include "dfg.h"
+#include "dfgparser.h"
+
+/* defined in dfgparser.y */
+extern NAT  dfg_LINENUMBER;
+extern BOOL dfg_IGNORETEXT;
+
+static NAT dfg_CountNewlines(char*);
+
+static __inline__ char* dfg_StringCopy(void)
+{
+  char *copy;
+  copy = (char*) memory_Malloc(yyleng+1);
+  strcpy(copy, yytext);
+  return copy;
+}
+
+/* Force the scanner to read the input character by character */
+#define YY_ALWAYS_INTERACTIVE 1
+/* Omit unused function yyunput */
+#define YY_NO_UNPUT 1
+/* Start conditions */
+#define TXT 1
+
+#line 3709 "dfgscanner.c"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines.  This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( yy_current_buffer->yy_is_interactive ) \
+		{ \
+		int c = '*', n; \
+		for ( n = 0; n < max_size && \
+			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+			buf[n] = (char) c; \
+		if ( c == '\n' ) \
+			buf[n++] = (char) c; \
+		if ( c == EOF && ferror( yyin ) ) \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+		result = n; \
+		} \
+	else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+		  && ferror( yyin ) ) \
+		YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	YY_USER_ACTION
+
+YY_DECL
+	{
+	register yy_state_type yy_current_state;
+	register char *yy_cp, *yy_bp;
+	register int yy_act;
+
+#line 84 "dfgscanner.l"
+
+
+#line 3863 "dfgscanner.c"
+
+	if ( yy_init )
+		{
+		yy_init = 0;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! yy_start )
+			yy_start = 1;	/* first start state */
+
+		if ( ! yyin )
+			yyin = stdin;
+
+		if ( ! yyout )
+			yyout = stdout;
+
+		if ( ! yy_current_buffer )
+			yy_current_buffer =
+				yy_create_buffer( yyin, YY_BUF_SIZE );
+
+		yy_load_buffer_state();
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+		yy_more_len = 0;
+		if ( yy_more_flag )
+			{
+			yy_more_len = yy_c_buf_p - yytext_ptr;
+			yy_more_flag = 0;
+			}
+		yy_cp = yy_c_buf_p;
+
+		/* Support of yytext. */
+		*yy_cp = yy_hold_char;
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = yy_start;
+yy_match:
+		while ( (yy_current_state = yy_nxt[yy_current_state][yy_ec[YY_SC_TO_UI(*yy_cp)]]) > 0 )
+			++yy_cp;
+
+		yy_current_state = -yy_current_state;
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+
+		YY_DO_BEFORE_ACTION;
+
+
+do_action:	/* This label is used only to access EOF actions. */
+
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+case 1:
+YY_RULE_SETUP
+#line 86 "dfgscanner.l"
+return DFG_AND;
+	YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 87 "dfgscanner.l"
+return DFG_AUTHOR;
+	YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 88 "dfgscanner.l"
+return DFG_AXIOMS;
+	YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 89 "dfgscanner.l"
+return DFG_BEGPROB;
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 90 "dfgscanner.l"
+return DFG_BY;
+	YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 91 "dfgscanner.l"
+return DFG_CLAUSE;
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 92 "dfgscanner.l"
+return DFG_CNF;
+	YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 93 "dfgscanner.l"
+return DFG_CONJECS;
+	YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 94 "dfgscanner.l"
+return DFG_DATE;
+	YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 95 "dfgscanner.l"
+return DFG_DESC;
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 96 "dfgscanner.l"
+return DFG_DNF;
+	YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 97 "dfgscanner.l"
+return DFG_ENDLIST;
+	YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 98 "dfgscanner.l"
+return DFG_ENDPROB;
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 99 "dfgscanner.l"
+return DFG_EQUAL;
+	YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 100 "dfgscanner.l"
+return DFG_EQUIV;
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 101 "dfgscanner.l"
+return DFG_EXISTS;
+	YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 102 "dfgscanner.l"
+return DFG_FALSE;
+	YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 103 "dfgscanner.l"
+return DFG_FORALL;
+	YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 104 "dfgscanner.l"
+return DFG_FORMULA;
+	YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 105 "dfgscanner.l"
+return DFG_FREELY;
+	YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 106 "dfgscanner.l"
+return DFG_FUNC;
+	YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 107 "dfgscanner.l"
+return DFG_GENERATED;
+	YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 108 "dfgscanner.l"
+return DFG_HYPOTH;
+	YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 109 "dfgscanner.l"
+return DFG_IMPLIED;
+	YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 110 "dfgscanner.l"
+return DFG_IMPLIES;
+	YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 111 "dfgscanner.l"
+return DFG_CLSLIST;
+	YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 112 "dfgscanner.l"
+return DFG_DECLLIST;
+	YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 113 "dfgscanner.l"
+return DFG_DESCLIST;
+	YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 114 "dfgscanner.l"
+return DFG_FORMLIST;
+	YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 115 "dfgscanner.l"
+return DFG_GENSET;
+	YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 116 "dfgscanner.l"
+return DFG_PRFLIST;
+	YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 117 "dfgscanner.l"
+return DFG_SETTINGS;
+	YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 118 "dfgscanner.l"
+return DFG_SYMLIST;
+	YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 119 "dfgscanner.l"
+return DFG_TERMLIST;
+	YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 120 "dfgscanner.l"
+return DFG_LOGIC;
+	YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 121 "dfgscanner.l"
+return DFG_NAME;
+	YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 122 "dfgscanner.l"
+return DFG_NOT;
+	YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 123 "dfgscanner.l"
+return DFG_OPERAT;
+	YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 124 "dfgscanner.l"
+return DFG_OR;
+	YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 125 "dfgscanner.l"
+return DFG_PRED;
+	YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 126 "dfgscanner.l"
+return DFG_PRDICAT;
+	YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 127 "dfgscanner.l"
+return DFG_QUANTIF;
+	YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 128 "dfgscanner.l"
+return DFG_SATIS;
+	YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 129 "dfgscanner.l"
+return DFG_DOMPRED;
+	YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 130 "dfgscanner.l"
+return DFG_SETFLAG;
+	YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 131 "dfgscanner.l"
+return DFG_PREC;
+	YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 132 "dfgscanner.l"
+return DFG_SORT;
+	YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 133 "dfgscanner.l"
+return DFG_SORTS;
+	YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 134 "dfgscanner.l"
+return DFG_STATUS;
+	YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 135 "dfgscanner.l"
+return DFG_STEP;
+	YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 136 "dfgscanner.l"
+return DFG_SUBSORT;
+	YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 137 "dfgscanner.l"
+return DFG_TRUE;
+	YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 138 "dfgscanner.l"
+return DFG_UNKNOWN;
+	YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 139 "dfgscanner.l"
+return DFG_UNSATIS;
+	YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 140 "dfgscanner.l"
+return DFG_VERSION;
+	YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 141 "dfgscanner.l"
+return DFG_MINUS1;
+	YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 143 "dfgscanner.l"
+/* one-line comment */
+	YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 144 "dfgscanner.l"
+{ /* Start of multiline comment */
+				  if (dfg_IGNORETEXT) {
+				    BEGIN(TXT);
+				    yymore();
+				  } else
+				    return DFG_OPENBRACE;
+				}
+	YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 151 "dfgscanner.l"
+return DFG_CLOSEBRACE;
+	YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 152 "dfgscanner.l"
+yymore();
+	YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 153 "dfgscanner.l"
+yymore();
+	YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 154 "dfgscanner.l"
+{ BEGIN(INITIAL);
+				  dfg_lval.string = dfg_StringCopy();
+				  dfg_LINENUMBER += dfg_CountNewlines(yytext);
+				  return DFG_TEXT;
+				}
+	YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 159 "dfgscanner.l"
+{ unsigned long n;
+                                  errno = 0;
+                                  n = strtoul(yytext, NULL, 10);
+				  if (errno != 0 || n > INT_MAX) {
+                                    misc_StartUserErrorReport();
+                                    misc_UserErrorReport("\n Number too big in line %d.\n",
+							 dfg_LINENUMBER);
+                                    misc_FinishUserErrorReport();
+                                  }
+                                  dfg_lval.number = (int) n;
+                                  return DFG_NUM;
+                                }
+	YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 171 "dfgscanner.l"
+{ dfg_lval.string = dfg_StringCopy();
+                                  return DFG_ID;
+                                }
+	YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 174 "dfgscanner.l"
+/* ignore */
+	YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 175 "dfgscanner.l"
+dfg_LINENUMBER++;
+	YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 176 "dfgscanner.l"
+return yytext[0];
+	YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 177 "dfgscanner.l"
+{ misc_StartUserErrorReport();
+                                  misc_UserErrorReport("\n Illegal character '");
+				  if (isprint((int)yytext[0]))
+				    misc_UserErrorReport("%c",yytext[0]);
+				  else
+				    misc_UserErrorReport("\\x%x", (unsigned int) yytext[0]);
+				  misc_UserErrorReport("' in line %d.\n", dfg_LINENUMBER);
+                                  misc_FinishUserErrorReport();
+                                }
+	YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 187 "dfgscanner.l"
+ECHO;
+	YY_BREAK
+#line 4301 "dfgscanner.c"
+			case YY_STATE_EOF(INITIAL):
+			case YY_STATE_EOF(TXT):
+				yyterminate();
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = yy_hold_char;
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed yyin at a new source and called
+			 * yylex().  If so, then we have to assure
+			 * consistency between yy_current_buffer and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			yy_n_chars = yy_current_buffer->yy_n_chars;
+			yy_current_buffer->yy_input_file = yyin;
+			yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state();
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++yy_c_buf_p;
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = yy_c_buf_p;
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer() )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				yy_did_buffer_switch_on_eof = 0;
+
+				if ( yywrap() )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * yytext, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				yy_c_buf_p =
+					yytext_ptr + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state();
+
+				yy_cp = yy_c_buf_p;
+				yy_bp = yytext_ptr + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				yy_c_buf_p =
+				&yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+				yy_current_state = yy_get_previous_state();
+
+				yy_cp = yy_c_buf_p;
+				yy_bp = yytext_ptr + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+	} /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+	{
+	register char *dest = yy_current_buffer->yy_ch_buf;
+	register char *source = yytext_ptr;
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( yy_current_buffer->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+	else
+		{
+		int num_to_read =
+			yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+			YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = yy_current_buffer;
+
+			int yy_c_buf_p_offset =
+				(int) (yy_c_buf_p - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					yy_flex_realloc( (void *) b->yy_ch_buf,
+							 b->yy_buf_size + 2 );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = yy_current_buffer->yy_buf_size -
+						number_to_move - 1;
+#endif
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+			yy_n_chars, num_to_read );
+
+		yy_current_buffer->yy_n_chars = yy_n_chars;
+		}
+
+	if ( yy_n_chars == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			yyrestart( yyin );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			yy_current_buffer->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	yy_n_chars += number_to_move;
+	yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+	yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+	yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+	return ret_val;
+	}
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+	{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+
+	yy_current_state = yy_start;
+
+	for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+		{
+		yy_current_state = yy_nxt[yy_current_state][(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1)];
+		}
+
+	return yy_current_state;
+	}
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+	{
+	register int yy_is_jam;
+
+	yy_current_state = yy_nxt[yy_current_state][1];
+	yy_is_jam = (yy_current_state <= 0);
+
+	return yy_is_jam ? 0 : yy_current_state;
+	}
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+	{
+	register char *yy_cp = yy_c_buf_p;
+
+	/* undo effects of setting up yytext */
+	*yy_cp = yy_hold_char;
+
+	if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		register int number_to_move = yy_n_chars + 2;
+		register char *dest = &yy_current_buffer->yy_ch_buf[
+					yy_current_buffer->yy_buf_size + 2];
+		register char *source =
+				&yy_current_buffer->yy_ch_buf[number_to_move];
+
+		while ( source > yy_current_buffer->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		yy_current_buffer->yy_n_chars =
+			yy_n_chars = yy_current_buffer->yy_buf_size;
+
+		if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+
+	yytext_ptr = yy_bp;
+	yy_hold_char = *yy_cp;
+	yy_c_buf_p = yy_cp;
+	}
+#endif	/* ifndef YY_NO_UNPUT */
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+	{
+	int c;
+
+	*yy_c_buf_p = yy_hold_char;
+
+	if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+			/* This was really a NUL. */
+			*yy_c_buf_p = '\0';
+
+		else
+			{ /* need more input */
+			int offset = yy_c_buf_p - yytext_ptr;
+			++yy_c_buf_p;
+
+			switch ( yy_get_next_buffer() )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					yyrestart( yyin );
+
+					/* fall through */
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( yywrap() )
+						return EOF;
+
+					if ( ! yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput();
+#else
+					return input();
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					yy_c_buf_p = yytext_ptr + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) yy_c_buf_p;	/* cast for 8-bit char's */
+	*yy_c_buf_p = '\0';	/* preserve yytext */
+	yy_hold_char = *++yy_c_buf_p;
+
+
+	return c;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+	{
+	if ( ! yy_current_buffer )
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+	yy_init_buffer( yy_current_buffer, input_file );
+	yy_load_buffer_state();
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+	{
+	if ( yy_current_buffer == new_buffer )
+		return;
+
+	if ( yy_current_buffer )
+		{
+		/* Flush out information for old buffer. */
+		*yy_c_buf_p = yy_hold_char;
+		yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+		yy_current_buffer->yy_n_chars = yy_n_chars;
+		}
+
+	yy_current_buffer = new_buffer;
+	yy_load_buffer_state();
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (yywrap()) processing, but the only time this flag
+	 * is looked at is after yywrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	yy_did_buffer_switch_on_eof = 1;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+	{
+	yy_n_chars = yy_current_buffer->yy_n_chars;
+	yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+	yyin = yy_current_buffer->yy_input_file;
+	yy_hold_char = *yy_c_buf_p;
+	}
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+	{
+	YY_BUFFER_STATE b;
+
+	b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	yy_init_buffer( b, file );
+
+	return b;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+	{
+	if ( ! b )
+		return;
+
+	if ( b == yy_current_buffer )
+		yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		yy_flex_free( (void *) b->yy_ch_buf );
+
+	yy_flex_free( (void *) b );
+	}
+
+
+#ifndef YY_ALWAYS_INTERACTIVE
+#ifndef YY_NEVER_INTERACTIVE
+extern int isatty YY_PROTO(( int ));
+#endif
+#endif
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+	{
+	yy_flush_buffer( b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+	b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+	b->yy_is_interactive = 0;
+#else
+	b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+	{
+	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == yy_current_buffer )
+		yy_load_buffer_state();
+	}
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+	{
+	YY_BUFFER_STATE b;
+
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	yy_switch_to_buffer( b );
+
+	return b;
+	}
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+	{
+	int len;
+	for ( len = 0; yy_str[len]; ++len )
+		;
+
+	return yy_scan_bytes( yy_str, len );
+	}
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+	{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = len + 2;
+	buf = (char *) yy_flex_alloc( n );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+	for ( i = 0; i < len; ++i )
+		buf[i] = bytes[i];
+
+	buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = yy_scan_buffer( buf, n );
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+	}
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+	{
+	if ( yy_start_stack_ptr >= yy_start_stack_depth )
+		{
+		yy_size_t new_size;
+
+		yy_start_stack_depth += YY_START_STACK_INCR;
+		new_size = yy_start_stack_depth * sizeof( int );
+
+		if ( ! yy_start_stack )
+			yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+		else
+			yy_start_stack = (int *) yy_flex_realloc(
+					(void *) yy_start_stack, new_size );
+
+		if ( ! yy_start_stack )
+			YY_FATAL_ERROR(
+			"out of memory expanding start-condition stack" );
+		}
+
+	yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+	BEGIN(new_state);
+	}
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+	{
+	if ( --yy_start_stack_ptr < 0 )
+		YY_FATAL_ERROR( "start-condition stack underflow" );
+
+	BEGIN(yy_start_stack[yy_start_stack_ptr]);
+	}
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+	{
+	return yy_start_stack[yy_start_stack_ptr - 1];
+	}
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+	{
+	(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+	}
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+		yytext[yyleng] = yy_hold_char; \
+		yy_c_buf_p = yytext + n; \
+		yy_hold_char = *yy_c_buf_p; \
+		*yy_c_buf_p = '\0'; \
+		yyleng = n; \
+		} \
+	while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+	{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+	}
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+	{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+	}
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+	{
+	return (void *) malloc( size );
+	}
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+	{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+	}
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+	{
+	free( ptr );
+	}
+
+#if YY_MAIN
+int main()
+	{
+	yylex();
+	return 0;
+	}
+#endif
+#line 187 "dfgscanner.l"
+
+
+static NAT dfg_CountNewlines(char* Text)
+{
+  NAT result = 0;
+  
+  while (*Text != 0) {
+    if (*Text++ == '\n')
+      result++;
+  }
+  return result;
+}
diff --git a/test/spass/doc-proof.c b/test/spass/doc-proof.c
new file mode 100644
index 0000000000000000000000000000000000000000..dadd69834c9ce2151c4660b19654c1e536a1199a
--- /dev/null
+++ b/test/spass/doc-proof.c
@@ -0,0 +1,247 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                 PROOF DOCUMENTATION                    * */
+/* *                                                        * */
+/* *  $Module:   DOCPROOF                                   * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "doc-proof.h"
+
+/**************************************************************/
+/* Global Variables                                           */
+/**************************************************************/
+
+int dp_DEPTH;
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+void dp_Init(void)
+{
+  dp_DEPTH = 0;
+}
+
+
+static void dp_FPrintDFGProof(LIST Clauses, const char *FilePrefix,
+			      FLAGSTORE Flags, PRECEDENCE Precedence)
+/*********************************************************
+  INPUT:   A list of clauses representing a proof, a
+           string indicating a file name prefix, a flag
+	   store and a precedence.
+  RETURNS: void.
+  EFFECT:  Outputs the proof in DFG proof format to
+           <FilePrefix>.prf
+**********************************************************/
+{
+  FILE   *Output;
+  CLAUSE Clause;
+  LIST   AxClauses,ConClauses,ProofClauses,Scan;
+  char   *name;
+
+  AxClauses = ConClauses = ProofClauses = list_Nil();
+  
+  name = memory_Malloc(sizeof(char)*(strlen(FilePrefix)+5));
+  sprintf(name,"%s.prf", FilePrefix);
+
+  Output = misc_OpenFile(name,"w");
+
+  fputs("begin_problem(Unknown).\n\n", Output);
+
+  fputs("list_of_descriptions.\n", Output);
+  fputs("name({*", Output);
+  fputs(FilePrefix, Output);
+  fputs("*}).\n", Output);
+  fputs("author({*SPASS ", Output);
+  fputs(misc_VERSION, Output);
+  fputs("*}).\n", Output);
+  fputs("status(unsatisfiable).\n", Output);
+  fputs("description({*File generated by SPASS containing a proof.*}).\n", Output);
+  fputs("end_of_list.\n\n", Output);
+
+  fputs("list_of_symbols.\n", Output);
+  fol_FPrintDFGSignature(Output);
+  fputs("end_of_list.\n\n", Output);
+
+  for (Scan=Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Clause = (CLAUSE)list_Car(Scan);
+    if (clause_IsFromInput(Clause)) {
+      if (clause_GetFlag(Clause, CONCLAUSE))
+	ConClauses = list_Cons(Clause, ConClauses);
+      else
+	AxClauses  = list_Cons(Clause, AxClauses);
+    }
+    else
+      ProofClauses  = list_Cons(Clause, ProofClauses);
+  }
+
+  ConClauses   = list_NReverse(ConClauses);
+  AxClauses    = list_NReverse(AxClauses);
+  ProofClauses = list_NReverse(ProofClauses);
+  
+  clause_FPrintCnfDFG(Output, FALSE, AxClauses, ConClauses, Flags, Precedence);
+  fputs("\nlist_of_proof(SPASS).\n", Output);
+  for (Scan=ProofClauses; !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+    clause_FPrintDFGStep(Output,list_Car(Scan),TRUE);
+  }
+  fputs("end_of_list.\n\n", Output);
+
+  fputs("end_problem.\n\n", Output);
+
+  misc_CloseFile(Output, name);
+  fputs("\nDFG Proof printed to: ", stdout);
+  puts(name);
+
+  list_Delete(ConClauses);
+  list_Delete(AxClauses);
+  list_Delete(ProofClauses);
+  memory_Free(name, sizeof(char)*(strlen(FilePrefix)+5));
+}
+
+LIST dp_PrintProof(PROOFSEARCH Search, LIST Clauses, const char *FilePrefix)
+/*********************************************************
+  INPUT:   A proofsearch object, a list of empty clauses and
+           the prefix of the output file name.
+  RETURNS: The list of clauses required for the proof.
+  MEMORY:  The returned list must be freed.
+  EFFECT:  The proof is printed both to standard output and
+           to the file <FilePrefix>.prf.
+**********************************************************/
+{
+  LIST ProofClauses,Scan,EmptyClauses,AllClauses, ReducedProof;
+  LIST Missing, Incomplete, SplitClauses;
+
+  FLAGSTORE Flags;
+
+  Flags = prfs_Store(Search);
+
+  Missing = pcheck_ConvertParentsInSPASSProof(Search, Clauses);
+  
+  if (!list_Empty(Missing)) {
+    puts("\nNOTE: clauses with following numbers have not been found:");
+    for (; !list_Empty(Missing); Missing = list_Pop(Missing))
+      printf("%d ", (int)list_Car(Missing)); 
+    putchar('\n');
+  }
+
+  EmptyClauses = list_Copy(Clauses); 
+  ProofClauses = list_Nil();
+  AllClauses   = list_Nconc(list_Copy(prfs_DocProofClauses(Search)),
+			    list_Nconc(list_Copy(prfs_UsableClauses(Search)),
+				       list_Copy(prfs_WorkedOffClauses(Search))));
+
+  /*
+   *  collect proof clauses by noodling upward in the 
+   *  proof tree, starting from <EmptyClauses>.
+   *  Before, add all splitting clauses to avoid gaps in split tree 
+   */
+
+  SplitClauses = list_Nil();
+  for (Scan = AllClauses; !list_Empty(Scan); Scan = list_Cdr(Scan)) 
+    if (clause_IsFromSplitting(list_Car(Scan))) 
+      SplitClauses = list_Cons(list_Car(Scan), SplitClauses);
+
+  /* mark all needed clauses */
+  pcheck_ClauseListRemoveFlag(EmptyClauses, MARKED);
+  pcheck_ClauseListRemoveFlag(AllClauses, MARKED);
+  pcheck_MarkRecursive(EmptyClauses);
+  pcheck_MarkRecursive(SplitClauses);
+  
+  /* collect all marked clauses */
+  ProofClauses = list_Nil();
+  for (Scan = AllClauses; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    if (clause_GetFlag(list_Car(Scan), MARKED))
+      ProofClauses = list_Cons(list_Car(Scan), ProofClauses); 
+  }
+
+  /* build reduced proof  */
+  ProofClauses = list_Nconc(ProofClauses, list_Copy(EmptyClauses));
+  ProofClauses = pcheck_ClauseNumberMergeSort(ProofClauses);
+  ReducedProof = pcheck_ReduceSPASSProof(ProofClauses); 
+
+  dp_SetProofDepth(pcheck_SeqProofDepth(ReducedProof));
+  
+  pcheck_ParentPointersToParentNumbers(AllClauses);
+  pcheck_ParentPointersToParentNumbers(Clauses);
+
+  /* check reduced proof for clauses whose parents have been marked as
+     incomplete (HIDDEN flag) by ConvertParentsInSPASSProof    */
+
+  Incomplete = list_Nil();
+  for (Scan = ReducedProof; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    if (clause_GetFlag(list_Car(Scan), HIDDEN))
+      Incomplete = list_Cons(list_Car(Scan), Incomplete);
+  }
+  if (!list_Empty(Incomplete)) {
+    puts("NOTE: Following clauses in reduced proof have incomplete parent sets:");
+    for (Scan = Incomplete; !list_Empty(Scan); Scan = list_Cdr(Scan))
+      printf("%d ", clause_Number(list_Car(Scan)));
+    putchar('\n');
+  }
+
+  printf("\n\nHere is a proof with depth %d, length %d :\n",
+	 dp_ProofDepth(), list_Length(ReducedProof));
+  clause_ListPrint(ReducedProof);
+
+  if (flag_GetFlagValue(Flags, flag_FPDFGPROOF))
+    dp_FPrintDFGProof(ReducedProof, FilePrefix, Flags, prfs_Precedence(Search));
+
+  fflush(stdout);
+
+  list_Delete(EmptyClauses);
+  list_Delete(AllClauses);
+  list_Delete(ProofClauses);
+  list_Delete(SplitClauses);
+  list_Delete(Incomplete); 
+
+  return ReducedProof;
+}
+
+
+
+
diff --git a/test/spass/doc-proof.h b/test/spass/doc-proof.h
new file mode 100644
index 0000000000000000000000000000000000000000..327cb4e94d223b48d1d4632d41cb4599ecc48091
--- /dev/null
+++ b/test/spass/doc-proof.h
@@ -0,0 +1,91 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                 PROOF DOCUMENTATION                    * */
+/* *                                                        * */
+/* *  $Module:   DOCPROOF                                   * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 2000, 2001            * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _DOC_PROOF_
+#define _DOC_PROOF_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "clause.h"
+#include "st.h"
+#include "sharing.h"
+#include "search.h"
+#include "doc-proof.h"
+#include "proofcheck.h"
+
+/**************************************************************/
+/* Data Structures and Constants                              */
+/**************************************************************/
+
+extern int dp_DEPTH;
+
+
+/**************************************************************/
+/* Macros                                                     */
+/**************************************************************/ 
+
+static __inline__ int dp_ProofDepth(void)
+{
+  return dp_DEPTH;
+}
+
+static __inline__ void dp_SetProofDepth(int Depth)
+{
+  dp_DEPTH = Depth;
+}
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/        
+
+void dp_Init(void);
+LIST dp_PrintProof(PROOFSEARCH, LIST, const char*);
+
+#endif
diff --git a/test/spass/flags.c b/test/spass/flags.c
new file mode 100644
index 0000000000000000000000000000000000000000..5cebfc610e24e164d7f2813295ddf172d1171c55
--- /dev/null
+++ b/test/spass/flags.c
@@ -0,0 +1,810 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                 FLAGS OF SPASS                         * */
+/* *                                                        * */
+/* *  $Module:   FLAGS                                      * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 35442 $                                        * */
+/* $State$                                            * */
+/* $Date: 2007-03-28 17:24:40 -0700 (Wed, 28 Mar 2007) $                             * */
+/* $Author: jeffc $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "flags.h"
+#include "misc.h"
+#include "stringsx.h"
+
+/**************************************************************/
+/* Global Declarations                                        */
+/**************************************************************/
+
+const int flag_CLEAN = -5;
+
+
+/**************************************************************/
+/* File Local Declarations                                    */
+/**************************************************************/
+
+/* Define flag properties */
+typedef struct {
+  int        minimum;
+  int        maximum;
+  FLAG_TYPE  type;
+  const char *name;
+} FLAG_PROPERTY;
+
+
+static FLAGARRAY     flag_DEFAULTSTORE;
+static FLAG_PROPERTY flag_PROPERTIES[flag_MAXFLAG];
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+static __inline__ void flag_InitIntern (FLAG_ID Flag, FLAG_TYPE Type,
+					const char *Name, int Value,
+					int Minimum, int Maximum)
+{
+  FLAG_PROPERTY *property;
+
+  flag_CheckFlagIdInRange(Flag);
+
+  property = &(flag_PROPERTIES[Flag]);
+
+  /* Set the flag type */
+  flag_CheckFlagTypeInRange(Type);
+  property->type = Type;
+
+  /* Set flag name */
+  property->name = Name;
+
+  /* Set flag minimum and maximum */
+  property->minimum = Minimum;
+  property->maximum = Maximum;
+
+  /* Set flag value */
+#ifdef CHECK
+  if (Value > Minimum && Value < Maximum) {
+#endif
+
+    flag_DEFAULTSTORE[Flag] = Value;
+
+#ifdef CHECK
+  }
+  else {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In flag_InitIntern: Default value out of range.");
+    misc_ErrorReport("\n Flag: %s. Value: %d.", Name, Value);
+    misc_FinishErrorReport();
+  }
+#endif
+}
+
+void flag_Init(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: Nothing.
+  EFFECT:  Sets all default values for known flags.
+  MEMORY:  Allocates memory for the default store.
+***************************************************************/
+{
+  /* Autonomous mode */
+  flag_InitIntern(flag_AUTO, flag_UNIQUE, "Auto", flag_AUTOON,
+		  flag_AUTOMIN, flag_AUTOMAX);
+
+  /* Set of Support Mode */
+  flag_InitIntern(flag_SOS, flag_UNIQUE, "SOS", flag_SOSOFF,
+		  flag_SOSMIN, flag_SOSMAX);
+
+  /* If set input is considered from stdin and printed to stdout */
+  flag_InitIntern(flag_STDIN, flag_UNIQUE, "Stdin", flag_STDINOFF,
+		  flag_STDINMIN, flag_STDINMAX);
+
+   /* If set interactive queries are possible */
+  flag_InitIntern(flag_INTERACTIVE, flag_UNIQUE, "Interactive", flag_INTERACTIVEOFF,
+		  flag_INTERACTIVEMIN, flag_INTERACTIVEMAX);
+
+  /* If set only Flotter CNF-translation is performed */
+  flag_InitIntern(flag_FLOTTER, flag_UNIQUE, "Flotter", flag_FLOTTEROFF,
+		  flag_FLOTTERMIN, flag_FLOTTERMAX);
+
+  /* Allowed number of loops, -1 means no restriction */
+  flag_InitIntern(flag_LOOPS, flag_UNIQUE, "Loops", flag_LOOPSUNLIMITED,
+		  flag_LOOPSMIN, flag_LOOPSMAX);
+
+  /* Allowed number of splits, -1 means no restriction */
+  flag_InitIntern(flag_SPLITS, flag_UNIQUE, "Splits", flag_SPLITSOFF,
+		  flag_SPLITSMIN, flag_SPLITSMAX);
+
+  /* Decides the level of sort usage: if 0 then no sort information is processed,
+     if 1 all negative monadic literals with a variable as its argument are processed,
+     if 2 all negative monadic literals are processed */
+  flag_InitIntern(flag_SORTS, flag_UNIQUE, "Sorts", flag_SORTSOFF,
+		  flag_SORTSMIN, flag_SORTSMAX);
+
+  /* ForwardSubsumption output not activated */
+  flag_InitIntern(flag_PSUB, flag_PRINTING, "PSub", flag_PSUBOFF,
+		  flag_PSUBMIN, flag_PSUBMAX);
+
+  /* Maximal memory allocation */
+  flag_InitIntern(flag_MEMORY, flag_UNIQUE, "Memory", flag_MEMORYUNLIMITED,
+		  flag_MEMORYMIN, flag_MEMORYMAX);
+
+  /* Document static soft typing  */
+  flag_InitIntern(flag_DOCSST, flag_PRINTING, "DocSST", flag_DOCSSTOFF,
+		  flag_DOCSSTMIN, flag_DOCSSTMAX);
+
+  /* Rewriting output not activated  */
+  flag_InitIntern(flag_PREW, flag_PRINTING, "PRew", flag_PREWOFF,
+		  flag_PREWMIN, flag_PREWMAX);
+
+  /* Contextual rewriting output not activated  */
+  flag_InitIntern(flag_PCRW, flag_PRINTING, "PCRw", flag_PCRWOFF,
+		  flag_PCRWMIN, flag_PCRWMAX);
+
+  /* Condensing output not activated  */
+  flag_InitIntern(flag_PCON, flag_PRINTING, "PCon", flag_PCONOFF,
+		  flag_PCONMIN, flag_PCONMAX);
+
+ /* Assignment Equation Deletion output not activated  */
+  flag_InitIntern(flag_PAED, flag_PRINTING, "PAED", flag_PAEDOFF,
+		  flag_PAEDMIN, flag_PAEDMAX);
+
+  /* Tautology output not activated  */
+  flag_InitIntern(flag_PTAUT, flag_PRINTING, "PTaut", flag_PTAUTOFF,
+		  flag_PTAUTMIN, flag_PTAUTMAX);
+
+  /* Output of obvious red. not activated  */
+  flag_InitIntern(flag_POBV, flag_PRINTING, "PObv", flag_POBVOFF,
+		  flag_POBVMIN, flag_POBVMAX);
+
+  /* SortSimplification output not activated  */
+  flag_InitIntern(flag_PSSI, flag_PRINTING, "PSSi", flag_PSSIOFF,
+		  flag_PSSIMIN, flag_PSSIMAX);
+
+  /* Static soft typing output not activated  */
+  flag_InitIntern(flag_PSST, flag_PRINTING, "PSST", flag_PSSTOFF,
+		  flag_PSSTMIN, flag_PSSTMAX);
+
+  /* Proof output not activated  */
+  flag_InitIntern(flag_DOCPROOF, flag_UNIQUE, "DocProof", flag_DOCPROOFOFF,
+		  flag_DOCPROOFMIN, flag_DOCPROOFMAX);
+
+  /* Matching Replacement Resolution output not activated  */
+  flag_InitIntern(flag_PMRR, flag_PRINTING, "PMRR", flag_PMRROFF,
+		  flag_PMRRMIN, flag_PMRRMAX);
+
+  /* Unit conflict output not activated  */
+  flag_InitIntern(flag_PUNC, flag_PRINTING, "PUnC", flag_PUNCOFF,
+		  flag_PUNCMIN, flag_PUNCMAX);
+
+  /* Derived clauses output not activated  */
+  flag_InitIntern(flag_PDER, flag_PRINTING, "PDer", flag_PDEROFF,
+		  flag_PDERMIN, flag_PDERMAX);
+
+  /* Given clause output activated  */
+  flag_InitIntern(flag_PGIVEN, flag_PRINTING, "PGiven", flag_PGIVENON,
+		  flag_PGIVENMIN, flag_PGIVENMAX);
+
+  /* If labels are created they are not printed  */
+  flag_InitIntern(flag_PLABELS, flag_PRINTING, "PLabels", flag_PLABELSOFF,
+		  flag_PLABELSMIN, flag_PLABELSMAX);
+
+  /* Kept clauses output not activated  */
+  flag_InitIntern(flag_PKEPT, flag_PRINTING, "PKept", flag_PKEPTOFF,
+		  flag_PKEPTMIN, flag_PKEPTMAX);
+
+  /* Split backtrack emphasizing not activated */
+  flag_InitIntern(flag_DOCSPLIT, flag_PRINTING, "DocSplit", flag_DOCSPLITOFF,
+		  flag_DOCSPLITMIN, flag_DOCSPLITMAX);
+
+  /* Print information about input clauses */
+  flag_InitIntern(flag_PPROBLEM, flag_PRINTING, "PProblem", flag_PPROBLEMON,
+		  flag_PPROBLEMMIN, flag_PPROBLEMMAX);
+
+  /* Print all derived empty clauses */
+  flag_InitIntern(flag_PEMPTYCLAUSE, flag_PRINTING, "PEmptyClause", flag_PEMPTYCLAUSEOFF,
+		  flag_PEMPTYCLAUSEMIN, flag_PEMPTYCLAUSEMAX);
+
+  /* Print statistic about memory, clauses */
+  flag_InitIntern(flag_PSTATISTIC, flag_PRINTING, "PStatistic", flag_PSTATISTICON,
+		  flag_PSTATISTICMIN, flag_PSTATISTICMAX);
+
+  /* Output saturated set of clauses to file, default no */
+  flag_InitIntern(flag_FPMODEL, flag_PRINTING, "FPModel", flag_FPMODELOFF,
+		  flag_FPMODELMIN, flag_FPMODELMAX);
+
+  /* Output proof in DFG format to file, default no */
+  flag_InitIntern(flag_FPDFGPROOF, flag_PRINTING, "FPDFGProof", flag_FPDFGPROOFOFF,
+		  flag_FPDFGPROOFMIN, flag_FPDFGPROOFMAX);
+
+  /* Output the actual values of all SPASS flags */
+  flag_InitIntern(flag_PFLAGS, flag_PRINTING, "PFlags", flag_PFLAGSOFF,
+		  flag_PFLAGSMIN, flag_PFLAGSMAX);
+
+  /* Optimized skolemization output not activated  */
+  flag_InitIntern(flag_POPTSKOLEM, flag_PRINTING, "POptSkolem", flag_POPTSKOLEMOFF,
+		  flag_POPTSKOLEMMIN, flag_POPTSKOLEMMAX);
+
+  /* Strong skolemization output not activated  */
+  flag_InitIntern(flag_PSTRSKOLEM, flag_PRINTING, "PStrSkolem", flag_PSTRSKOLEMOFF,
+		  flag_PSTRSKOLEMMIN, flag_PSTRSKOLEMMAX);
+
+  /* Printing of clauses deleted by bound restriction not activated  */
+  flag_InitIntern(flag_PBDC, flag_PRINTING, "PBDC", flag_PBDCOFF,
+		  flag_PBDCMIN, flag_PBDCMAX);
+
+  /* Printing of bound increase actions  */
+  flag_InitIntern(flag_PBINC, flag_PRINTING, "PBInc", flag_PBINCOFF,
+		  flag_PBINCMIN, flag_PBINCMAX);
+
+  /* Application of definitions  output activated  */
+  flag_InitIntern(flag_PAPPLYDEFS, flag_PRINTING, "PApplyDefs", flag_PAPPLYDEFSOFF,
+		  flag_PAPPLYDEFSMIN, flag_PAPPLYDEFSMAX);
+
+  /* Amount of time (seconds) available to SPASS, -1 means arbitrary */
+  flag_InitIntern(flag_TIMELIMIT, flag_UNIQUE, "TimeLimit", flag_TIMELIMITUNLIMITED,
+		  flag_TIMELIMITMIN, flag_TIMELIMITMAX);
+  
+  /* Select: 0 -> no selection, 1 -> select if multiple maximal literals, 2 -> always select */
+  flag_InitIntern(flag_SELECT, flag_UNIQUE, "Select", flag_SELECTIFSEVERALMAXIMAL,
+		  flag_SELECTMIN, flag_SELECTMAX);
+
+  /* Activates the inference rule Empty Sort */
+  flag_InitIntern(flag_IEMS, flag_INFERENCE, "IEmS", flag_EMPTYSORTOFF,
+		  flag_EMPTYSORTMIN, flag_EMPTYSORTMAX);
+
+  /* Activates the inference rule Sort Resolution */
+  flag_InitIntern(flag_ISOR, flag_INFERENCE, "ISoR", flag_SORTRESOLUTIONOFF,
+		  flag_SORTRESOLUTIONMIN, flag_SORTRESOLUTIONMAX);
+
+  /* Activates the inference rule Equality Resolution */
+  flag_InitIntern(flag_IEQR, flag_INFERENCE, "IEqR", flag_EQUALITYRESOLUTIONOFF,
+		  flag_EQUALITYRESOLUTIONMIN, flag_EQUALITYRESOLUTIONMAX);
+
+  /* Activates the inference rule Reflexivity Resolution */
+  flag_InitIntern(flag_IERR, flag_INFERENCE, "IERR", flag_REFLEXIVITYRESOLUTIONOFF,
+		  flag_REFLEXIVITYRESOLUTIONMIN, flag_REFLEXIVITYRESOLUTIONMAX);
+
+  /* Activates the inference rule Equality Factoring */
+  flag_InitIntern(flag_IEQF, flag_INFERENCE, "IEqF", flag_EQUALITYFACTORINGOFF,
+		  flag_EQUALITYFACTORINGMIN, flag_EQUALITYFACTORINGMAX);
+
+  /* Activates the inference rule Merging Paramodulation */
+  flag_InitIntern(flag_IMPM, flag_INFERENCE, "IMPm", flag_MERGINGPARAMODULATIONOFF,
+		  flag_MERGINGPARAMODULATIONMIN, flag_MERGINGPARAMODULATIONMAX);
+
+  /* Activates the inference rule Superposition Right */
+  flag_InitIntern(flag_ISPR, flag_INFERENCE, "ISpR", flag_SUPERPOSITIONRIGHTOFF,
+		  flag_SUPERPOSITIONRIGHTMIN, flag_SUPERPOSITIONRIGHTMAX);
+  
+  /* Inference rule Ordered Paramodulation not active */  
+  flag_InitIntern(flag_IOPM, flag_INFERENCE, "IOPm", flag_ORDEREDPARAMODULATIONOFF,
+		  flag_ORDEREDPARAMODULATIONMIN, flag_ORDEREDPARAMODULATIONMAX);
+
+  /*   Inference rule Paramodulation not active */  
+  flag_InitIntern(flag_ISPM, flag_INFERENCE, "ISPm", flag_STANDARDPARAMODULATIONOFF,
+		  flag_STANDARDPARAMODULATIONMIN, flag_STANDARDPARAMODULATIONMAX);   
+
+  /* Activates the inference rule Superposition Left */
+  flag_InitIntern(flag_ISPL, flag_INFERENCE, "ISpL", flag_SUPERPOSITIONLEFTOFF,
+		  flag_SUPERPOSITIONLEFTMIN, flag_SUPERPOSITIONLEFTMAX);
+  
+  /* Activates the inference rule Ordered Resolution */
+  flag_InitIntern(flag_IORE, flag_INFERENCE, "IORe", flag_ORDEREDRESOLUTIONOFF,
+		  flag_ORDEREDRESOLUTIONMIN, flag_ORDEREDRESOLUTIONMAX);
+
+  /* Activates the inference rule Standard Resolution */
+  flag_InitIntern(flag_ISRE, flag_INFERENCE, "ISRe", flag_STANDARDRESOLUTIONOFF,
+		  flag_STANDARDRESOLUTIONMIN, flag_STANDARDRESOLUTIONMAX);
+
+  /* Activates the inference rule Standard Hyperresolution */
+  flag_InitIntern(flag_ISHY, flag_INFERENCE, "ISHy", flag_STANDARDHYPERRESOLUTIONOFF,
+		  flag_STANDARDHYPERRESOLUTIONMIN, flag_STANDARDHYPERRESOLUTIONMAX);
+  
+  /* Activates the inference rule Ordered Hyperresolution */
+  flag_InitIntern(flag_IOHY, flag_INFERENCE, "IOHy", flag_ORDEREDHYPERRESOLUTIONOFF,
+		  flag_ORDEREDHYPERRESOLUTIONMIN, flag_ORDEREDHYPERRESOLUTIONMAX);
+
+  /* Activates the inference rule UR Resolution */
+  flag_InitIntern(flag_IURR, flag_INFERENCE, "IURR", flag_UNITRESULTINGRESOLUTIONOFF,
+		  flag_UNITRESULTINGRESOLUTIONMIN, flag_UNITRESULTINGRESOLUTIONMAX);
+
+  /* Activates the inference rule Ordered Factoring */
+  flag_InitIntern(flag_IOFC, flag_INFERENCE, "IOFc", flag_FACTORINGOFF,
+		  flag_FACTORINGMIN, flag_FACTORINGMAX);
+
+    /* Activates the inference rule Standard Factoring */
+  flag_InitIntern(flag_ISFC, flag_INFERENCE, "ISFc", flag_STANDARDFACTORINGOFF,
+		  flag_STANDARDFACTORINGMIN, flag_STANDARDFACTORINGMAX);
+
+  /* Activates the inference rule Bounded Unit Resolution */
+  flag_InitIntern(flag_IBUR, flag_INFERENCE, "IBUR", flag_BOUNDEDDEPTHUNITRESOLUTIONOFF,
+		  flag_BOUNDEDDEPTHUNITRESOLUTIONMIN, flag_BOUNDEDDEPTHUNITRESOLUTIONMAX);
+
+  /* Activates the inference rule Definition Application */
+  flag_InitIntern(flag_IDEF, flag_INFERENCE, "IDEF", flag_DEFINITIONAPPLICATIONOFF,
+		  flag_DEFINITIONAPPLICATIONMIN, flag_DEFINITIONAPPLICATIONMAX);
+
+  /* Activates the inference rule  Unit Resolution */
+  flag_InitIntern(flag_IUNR, flag_INFERENCE, "IUnR", flag_UNITRESOLUTIONOFF,
+		  flag_UNITRESOLUTIONMIN, flag_UNITRESOLUTIONMAX);
+  
+  /* Activates Forward Rewriting */
+  flag_InitIntern(flag_RFREW, flag_REDUCTION, "RFRew", flag_RFREWOFF,
+		  flag_RFREWMIN, flag_RFREWMAX);
+
+  /* Activates Backward Rewriting */
+  flag_InitIntern(flag_RBREW, flag_REDUCTION, "RBRew", flag_RBREWOFF,
+		  flag_RBREWMIN, flag_RBREWMAX);
+
+  /* Activates Forward Contextual Rewriting */
+  flag_InitIntern(flag_RFCRW, flag_REDUCTION, "RFCRw", flag_RFCRWOFF,
+		  flag_RFCRWMIN, flag_RFCRWMAX);
+
+  /* Activates Backward Contextual Rewriting */
+  flag_InitIntern(flag_RBCRW, flag_REDUCTION, "RBCRw", flag_RBCRWOFF,
+		  flag_RBCRWMIN, flag_RBCRWMAX);
+
+  /* Activates Unit Conflict */
+  flag_InitIntern(flag_RUNC, flag_REDUCTION, "RUnC", flag_RUNCOFF,
+		  flag_RUNCMIN, flag_RUNCMAX);
+
+  /* Activates Terminator */
+  flag_InitIntern(flag_RTER, flag_REDUCTION, "RTer", flag_RTEROFF,
+		  flag_RTERMIN, flag_RTERMAX);
+
+  /* Activates Forward Subsumption */
+  flag_InitIntern(flag_RFSUB, flag_REDUCTION, "RFSub", flag_RFSUBOFF,
+		  flag_RFSUBMIN, flag_RFSUBMAX);
+
+  /* Activates Backward Subsumption */
+  flag_InitIntern(flag_RBSUB, flag_REDUCTION, "RBSub", flag_RBSUBOFF,
+		  flag_RBSUBMIN, flag_RBSUBMAX);
+
+  /* Activates Forward Matching Replacement Resolution */
+  flag_InitIntern(flag_RFMRR, flag_REDUCTION, "RFMRR", flag_RFMRROFF,
+		  flag_RFMRRMIN, flag_RFMRRMAX);
+
+  /* Activates Backward Matching Replacement Resolution */
+  flag_InitIntern(flag_RBMRR, flag_REDUCTION, "RBMRR", flag_RBMRROFF,
+		  flag_RBMRRMIN, flag_RBMRRMAX);
+
+  /* Activates the reduction rule Obvious Reduction */
+  flag_InitIntern(flag_ROBV, flag_REDUCTION, "RObv", flag_ROBVOFF,
+		  flag_ROBVMIN, flag_ROBVMAX);
+
+  /* Activates the reduction rule Tautology */
+  flag_InitIntern(flag_RTAUT, flag_REDUCTION, "RTaut", flag_RTAUTOFF,
+		  flag_RTAUTMIN, flag_RTAUTMAX);
+
+  /* Activates the reduction rule Sort Simplification */
+  flag_InitIntern(flag_RSSI, flag_REDUCTION, "RSSi", flag_RSSIOFF,
+		  flag_RSSIMIN, flag_RSSIMAX);
+
+  /* Activates static soft typing */
+  flag_InitIntern(flag_RSST, flag_REDUCTION, "RSST", flag_RSSTOFF,
+		  flag_RSSTMIN, flag_RSSTMAX);
+
+  /* Activates Assignment Equation Deletion */
+  /* If set to 2 it also eliminates equations */
+  /* that are redundant only in non-trivial domains */
+  flag_InitIntern(flag_RAED, flag_REDUCTION, "RAED", flag_RAEDOFF,
+		  flag_RAEDMIN, flag_RAEDMAX);
+
+  /* Activates Condensing */
+  flag_InitIntern(flag_RCON, flag_REDUCTION, "RCon", flag_RCONOFF,
+		  flag_RCONMIN, flag_RCONMAX);
+
+  /* Activates reduction of input clauses */
+  flag_InitIntern(flag_RINPUT, flag_UNIQUE, "RInput", flag_RINPUTON,
+		  flag_RINPUTMIN, flag_RINPUTMAX);
+
+  /* Activates application of definitions */
+  flag_InitIntern(flag_APPLYDEFS, flag_UNIQUE, "ApplyDefs", flag_APPLYDEFSOFF,
+		  flag_APPLYDEFSMIN, flag_APPLYDEFSMAX);
+
+  /* If true usable and worked off are completely interreduced; otherwise only worked off */
+  flag_InitIntern(flag_FULLRED, flag_UNIQUE, "FullRed", flag_FULLREDON,
+		  flag_FULLREDMIN, flag_FULLREDMAX);
+
+  /* Activates unit saturation of input clauses */
+  flag_InitIntern(flag_SATINPUT, flag_UNIQUE, "SatInput", flag_SATINPUTOFF,
+		  flag_SATINPUTMIN, flag_SATINPUTMAX);
+
+  /* Ratio between weight and depth selection of clauses from usable */
+  flag_InitIntern(flag_WDRATIO, flag_UNIQUE, "WDRatio", 5,
+		  flag_WDRATIOMIN, flag_WDRATIOMAX);
+
+  /* Factor to divide the weight of conjecture clauses to prefer them for selection */
+  flag_InitIntern(flag_PREFCON, flag_UNIQUE, "PrefCon", flag_PREFCONUNCHANGED, 
+		  flag_PREFCONMIN, flag_PREFCONMAX);
+
+  /* Weight of a function symbol; weight of clause is used to select given */
+  flag_InitIntern(flag_FUNCWEIGHT, flag_UNIQUE, "FuncWeight", 1,
+		  flag_FUNCWEIGHTMIN, flag_FUNCWEIGHTMAX);
+
+  /* Weight of a variable symbol; weight of clause is used to select given */
+  flag_InitIntern(flag_VARWEIGHT, flag_UNIQUE, "VarWeight", 1,
+		  flag_VARWEIGHTMIN, flag_VARWEIGHTMAX);
+
+  /* Prefer the selection of clauses with many variable occurrences */
+  flag_InitIntern(flag_PREFVAR, flag_UNIQUE, "PrefVar", flag_PREFVAROFF,
+		  flag_PREFVARMIN, flag_PREFVARMAX);
+
+  /* The type of bound: 0 (no bound) 1 (by clause weight) 2 (by clause term depth) */
+  flag_InitIntern(flag_BOUNDMODE, flag_UNIQUE, "BoundMode", flag_BOUNDMODEUNLIMITED,
+		  flag_BOUNDMODEMIN, flag_BOUNDMODEMAX);
+
+  /* The initial bound value, where -1 means no restriction */
+  flag_InitIntern(flag_BOUNDSTART, flag_UNIQUE, "BoundStart", flag_BOUNDSTARTUNLIMITED,
+		  flag_BOUNDSTARTMIN, flag_BOUNDSTARTMAX);
+
+  /* The number of bound saturation loops */
+  flag_InitIntern(flag_BOUNDLOOPS, flag_UNIQUE, "BoundLoops", 1,
+		  flag_BOUNDLOOPSMIN, flag_BOUNDLOOPSMAX);
+
+  /* Flags for selecting the ordering to use */
+  flag_InitIntern(flag_ORD, flag_UNIQUE, "Ordering", flag_ORDKBO,
+		  flag_ORDMIN, flag_ORDMAX);
+
+  /* CNF flag, if set optimized skolemization is performed */
+  flag_InitIntern(flag_CNFOPTSKOLEM, flag_UNIQUE, "CNFOptSkolem", flag_CNFOPTSKOLEMON,
+		  flag_CNFOPTSKOLEMMIN, flag_CNFOPTSKOLEMMAX);
+
+  /* CNF flag, restricts the number of optimized skolemization proof steps */
+  flag_InitIntern(flag_CNFPROOFSTEPS, flag_UNIQUE, "CNFProofSteps", 100,
+		  flag_CNFPROOFSTEPSMIN, flag_CNFPROOFSTEPSMAX);
+
+  /* CNF flag, if set renaming is performed */
+  flag_InitIntern(flag_CNFRENAMING, flag_UNIQUE, "CNFRenaming", flag_CNFRENAMINGON,
+		  flag_CNFRENAMINGMIN, flag_CNFRENAMINGMAX);
+
+  /* CNF flag, if set renaming is printed */
+  flag_InitIntern(flag_CNFPRENAMING, flag_UNIQUE, "CNFPRenaming", flag_CNFPRENAMINGOFF,
+		  flag_CNFPRENAMINGMIN, flag_CNFPRENAMINGMAX);
+
+  /* CNF flag, if set strong skolemization is performed */
+  flag_InitIntern(flag_CNFSTRSKOLEM, flag_UNIQUE, "CNFStrSkolem", flag_CNFSTRSKOLEMON,
+		  flag_CNFSTRSKOLEMMIN, flag_CNFSTRSKOLEMMAX);
+
+  /* CNF flag, if set reductions on equality literals are performed */
+  flag_InitIntern(flag_CNFFEQREDUCTIONS, flag_UNIQUE, "CNFFEqR", flag_CNFFEQREDUCTIONSON,
+		  flag_CNFFEQREDUCTIONSMIN, flag_CNFFEQREDUCTIONSMAX);
+
+  /* dfg2otter flag, if set input options for otter are generated */
+  flag_InitIntern(flag_TDFG2OTTEROPTIONS, flag_UNIQUE, "TDfg2OtterOptions", flag_TDFG2OTTEROPTIONSOFF,
+		  flag_TDFG2OTTEROPTIONSMIN, flag_TDFG2OTTEROPTIONSMAX);
+}
+
+
+FLAGSTORE flag_DefaultStore(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: Default flag store.
+***************************************************************/
+{
+  return flag_DEFAULTSTORE;
+}
+
+
+void flag_Print(FLAGSTORE Store)
+/**************************************************************
+  INPUT:   A FlagStore.
+  RETURNS: Nothing.
+  EFFECT:  Prints the values of all flags to stdout.
+***************************************************************/
+{
+  flag_FPrint(stdout, Store);
+}
+
+
+void flag_FPrint(FILE* File, FLAGSTORE Store)
+/**************************************************************
+  INPUT:   A File to print to, and a FlagStore.
+  RETURNS: Nothing.
+  EFFECT:  Prints the values of all flags to File.
+***************************************************************/
+{
+  FLAG_ID  i;
+  char name[30];
+  
+  fputs("list_of_settings(SPASS).{*", File);
+
+  for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i+= (FLAG_ID) 3) {
+    sprintf(name,"set_flag(%s,%d).", flag_Name(i), flag_GetFlagValue(Store, i));
+    fprintf(File,"\n %-30s",name);
+    if (i+1 < flag_MAXFLAG) {
+      sprintf(name,"set_flag(%s,%d).", flag_Name(i+ (FLAG_ID) 1), flag_GetFlagValue(Store, i+ (FLAG_ID) 1));
+      fprintf(File," %-30s",name);
+      if (i+2 < flag_MAXFLAG) {
+	sprintf(name," set_flag(%s,%d).", flag_Name(i+ (FLAG_ID) 2), flag_GetFlagValue(Store, i+ (FLAG_ID) 2));
+	fprintf(File," %-30s",name);
+      }
+    }
+  }
+  fputs("*}\nend_of_list.\n", File);
+}
+
+
+BOOL flag_Lookup(const char* String)
+/**************************************************************
+  INPUT:   A string <String>.
+  RETURNS: TRUE iff <String> is the string of a known flag.
+***************************************************************/
+{
+  return (flag_Id(String) != -1);
+}
+
+
+FLAG_ID flag_Id(const char* String)
+/**************************************************************
+  INPUT:   A string <String>.
+  RETURNS: The identification of the flag <String> if it exists
+           -1 otherwise.
+***************************************************************/
+{
+  FLAG_ID i;
+
+  for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i++)
+    if (string_Equal(flag_Name(i), String))
+      return i;
+
+  return (FLAG_ID) -1;
+}
+
+
+const char* flag_Name(FLAG_ID Flag)
+/**************************************************************
+  INPUT:   A FlagId.
+  RETURNS: The name of the flag <Flag>.
+  EFFECT:  Looks up the name of the flag <Flag> and returns it,
+           if it exists.
+***************************************************************/
+{
+  flag_CheckFlagIdInRange(Flag);
+ 
+  return(flag_PROPERTIES[Flag].name);
+}
+
+
+int flag_Minimum(FLAG_ID Flag)
+/**************************************************************
+  INPUT:   A FlagId.
+  RETURNS: The first integer below the minimal legal value 
+           of the flag.
+***************************************************************/
+{
+  flag_CheckFlagIdInRange(Flag);
+ 
+  return flag_PROPERTIES[Flag].minimum;
+}
+
+
+int flag_Maximum(FLAG_ID Flag)
+/**************************************************************
+  INPUT:   A FlagId.
+  RETURNS: The first integer above the maximal legal value 
+           of the flag.
+***************************************************************/
+{
+  flag_CheckFlagIdInRange(Flag);
+ 
+  return flag_PROPERTIES[Flag].maximum;
+}
+
+
+FLAG_TYPE flag_Type(FLAG_ID Flag)
+/**************************************************************
+  INPUT:   A FlagId.
+  RETURNS: The flag type.
+***************************************************************/
+{
+  flag_CheckFlagIdInRange(Flag);
+
+  return flag_PROPERTIES[Flag].type;  
+}
+
+
+void flag_ClearInferenceRules(FLAGSTORE Store)
+/**************************************************************
+  INPUT:   A FlagStore.
+  RETURNS: Nothing.
+  EFFECT:  Turns all inference rules off.
+***************************************************************/
+{
+  FLAG_ID i;
+
+  for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i++) {
+    if (flag_IsInference(i))
+      flag_SetFlagValue(Store, i, flag_OFF);
+  }
+}
+
+
+void flag_ClearReductionRules(FLAGSTORE Store)
+/**************************************************************
+  INPUT:   A FlagStore.
+  RETURNS: Nothing.
+  EFFECT:  Turns all reduction rules off.
+***************************************************************/
+{
+  FLAG_ID i;
+
+  for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i++) {
+    if (flag_IsReduction(i)) {
+        flag_SetFlagValue(Store, i, flag_OFF);
+    }
+  }
+}
+
+
+void flag_ClearPrinting(FLAGSTORE Store)
+/**************************************************************
+  INPUT:   A FlagStore.
+  RETURNS: Nothing.
+  EFFECT:  Turns all printing off.
+***************************************************************/
+{
+
+  FLAG_ID i;
+
+  for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i++) {
+    if (flag_IsPrinting(i))
+      flag_SetFlagValue(Store, i, flag_OFF);
+  }
+}
+
+
+void flag_SetReductionsToDefaults(FLAGSTORE Store)
+/**************************************************************
+  INPUT:   A FlagStore.
+  RETURNS: Nothing.
+  EFFECT:  Sets all reduction rules to defaults.
+***************************************************************/
+{
+
+  FLAG_ID i;
+
+  for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i++) {
+    if (flag_IsReduction(i))
+      flag_SetFlagToDefault(Store, i);
+  }
+}
+
+
+void flag_InitFlotterSubproofFlags(FLAGSTORE Source, FLAGSTORE Target)
+/**************************************************************
+  INPUT:   Two flag stores.
+  RETURNS: Nothing.
+  EFFECT:  Initializes the flag store <Target> to the values required by a
+           Flotter subproof. The other flag store is needed to take over
+           some flags, e.g. DOCPROOF.
+***************************************************************/
+{
+  /* Deactivate printing */
+  flag_ClearPrinting(Target);
+
+  /* Deactivate inference rules */
+  flag_ClearInferenceRules(Target);
+
+  /* Set reductions to default values */
+  flag_SetReductionsToDefaults(Target);
+
+  flag_SetFlagToDefault(Target, flag_CNFFEQREDUCTIONS);
+  flag_SetFlagToDefault(Target, flag_RINPUT);
+ 
+  /* Copy flag_DOCPROOF and flag_CNFPROOFSTEPS */
+  flag_TransferFlag(Source, Target, flag_DOCPROOF);  
+  flag_TransferFlag(Source, Target, flag_CNFPROOFSTEPS);
+
+  /* Activate BoundedDepthUnitResolution */
+  flag_SetFlagValue(Target, flag_IBUR, flag_BOUNDEDDEPTHUNITRESOLUTIONON);
+
+  /* Activate KBO */
+  flag_SetFlagValue(Target, flag_ORD, flag_ORDKBO);
+
+  /* Transfer Weights for Terms */
+  flag_TransferFlag(Source, Target, flag_FUNCWEIGHT);  
+  flag_TransferFlag(Source, Target, flag_VARWEIGHT);
+
+  /* Transfer Selection Strategy, not needed for depth bounded */
+  /* unit resolution (see above) but for other potentially useful inference rules */
+  flag_TransferFlag(Source, Target, flag_SELECT);  
+}
+
+
+void flag_InitFlotterFlags(FLAGSTORE Source, FLAGSTORE Target)
+/**************************************************************
+  INPUT:   Two flag stores.
+  RETURNS: Nothing.
+  EFFECT:  Initalizes the flag store <Target> to the values required by
+           Flotter. The other flag store is needed to set
+           some flags, e.g. DOCPROOF.
+***************************************************************/
+{
+  flag_InitFlotterSubproofFlags(Source, Target);
+
+  /* Set ordering to default value */
+  flag_SetFlagToDefault(Target, flag_ORD);
+
+  /* Set weighting flags to default values */
+  flag_SetFlagToDefault(Target, flag_FUNCWEIGHT);
+  flag_SetFlagToDefault(Target, flag_VARWEIGHT);
+
+  /* Copy given values to diverse flags */
+  flag_TransferFlag(Source, Target, flag_CNFRENAMING);
+  flag_TransferFlag(Source, Target, flag_CNFOPTSKOLEM);
+  flag_TransferFlag(Source, Target, flag_CNFSTRSKOLEM);
+  flag_TransferFlag(Source, Target, flag_PAPPLYDEFS);
+  flag_TransferFlag(Source, Target, flag_PBDC);
+  flag_TransferFlag(Source, Target, flag_PBINC);
+  flag_TransferFlag(Source, Target, flag_CNFPRENAMING);
+  flag_TransferFlag(Source, Target, flag_POPTSKOLEM);
+  flag_TransferFlag(Source, Target, flag_PSTRSKOLEM);
+  flag_TransferFlag(Source, Target, flag_INTERACTIVE);
+}
+
+
+void flag_CheckStore(FLAGSTORE Store) 
+/**************************************************************
+  INPUT:   A flag store.
+  RETURNS: TRUE is the flag store is in a valid state,
+           FALSE otherwise.
+***************************************************************/
+{
+  FLAG_ID i;
+  FLAG value;
+
+  /* check all flags */
+  for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i ++) {
+    /* Get flag value first. We can't use flag_GetFlagValue() since it
+       prints an error message and exits, if a flag is clean. A flag can
+       be clean, only reading it is an error (for most functions).
+    */
+
+    value = Store[i];
+    if (value != flag_CLEAN) {
+      flag_CheckFlagValueInRange(i,value);
+    }
+  }
+}
diff --git a/test/spass/flags.h b/test/spass/flags.h
new file mode 100644
index 0000000000000000000000000000000000000000..2a9e1a55de15442084c0b91c06af890ac28b5fce
--- /dev/null
+++ b/test/spass/flags.h
@@ -0,0 +1,1117 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                 FLAGS OF SPASS                         * */
+/* *                                                        * */
+/* *  $Module:   FLAGS                                      * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _FLAGS_
+#define _FLAGS_
+
+#include <limits.h>
+#include <stdio.h>
+
+#include "memory.h"
+#include "misc.h"
+
+/**************************************************************/
+/* Data Structures and Constants                              */
+/**************************************************************/
+
+extern const int flag_CLEAN;
+
+/* Define the legal values for all flags as data types.
+  
+   All flags have a minimum and a maximum. Legal values are 
+   within that range, *excluding* the minimum, maximum value. By using 
+   flag_XXXMIN and flag_XXXMAX we have a simple test for a 
+   flag's correctness:
+
+     if
+       flag value <= flag minimum 
+       or flag value >= flag maximum
+     then
+       the flag has an illegal state.
+
+   Boolean flags have two legal values:
+    * flag_XXXOFF ( = 0)
+    * flag_XXXON ( = 1)
+*/
+
+/* State definitions for boolean flags */
+typedef enum { flag_OFF = 0,
+	       flag_ON  = 1
+} FLAG_BOOLEAN;
+
+/* State definitions for flag_APPLYDEFS */
+typedef enum { flag_APPLYDEFSMIN = -1,
+               flag_APPLYDEFSOFF = flag_OFF,
+               flag_APPLYDEFSMAX = INT_MAX
+} FLAG_APPLYDEFSTYPE;
+
+/* State definitions for flag_AUTO */
+typedef enum { flag_AUTOMIN = -1,
+	       flag_AUTOOFF = flag_OFF,
+	       flag_AUTOON  = flag_ON,
+	       flag_AUTOMAX
+} FLAG_AUTOTYPE;
+
+/* State definitions for flag_BOUNDLOOPS */
+typedef enum { flag_BOUNDLOOPSMIN = 0,
+	       flag_BOUNDLOOPSMAX = INT_MAX
+} FLAG_BOUNDLOOPSTYPE;
+
+/* State definitions for flag_BOUNDMODE */
+typedef enum { flag_BOUNDMODEMIN = -1,
+	       flag_BOUNDMODEUNLIMITED,
+	       flag_BOUNDMODERESTRICTEDBYWEIGHT, 
+	       flag_BOUNDMODERESTRICTEDBYDEPTH,
+	       flag_BOUNDMODEMAX
+} FLAG_BOUNDMODETYPE;
+
+/* State definitions for flag_BOUNDSTART */
+typedef enum { flag_BOUNDSTARTMIN = -2,
+	       flag_BOUNDSTARTUNLIMITED,
+	       flag_BOUNDSTARTMAX = INT_MAX
+} FLAG_BOUNDSTARTTYPE;
+
+/* State definitions for flag_CNFFEQREDUCTIONS */
+typedef enum { flag_CNFFEQREDUCTIONSMIN = -1,
+               flag_CNFFEQREDUCTIONSOFF = flag_OFF,
+               flag_CNFFEQREDUCTIONSON  = flag_ON,
+               flag_CNFFEQREDUCTIONSMAX
+} FLAG_CNFFEQREDUCTIONSTYPE;
+
+/* State definitions for flag_CNFOPTSKOLEM */
+typedef enum { flag_CNFOPTSKOLEMMIN = -1,
+               flag_CNFOPTSKOLEMOFF = flag_OFF,
+               flag_CNFOPTSKOLEMON  = flag_ON,
+               flag_CNFOPTSKOLEMMAX
+} flag_CNFOPTSKOLEMTYPE;
+
+/* State definitions for flag_CNFPRENAMING */
+typedef enum { flag_CNFPRENAMINGMIN = -1,
+               flag_CNFPRENAMINGOFF = flag_OFF,
+               flag_CNFPRENAMINGON  = flag_ON,
+               flag_CNFPRENAMINGMAX
+} FLAG_CNFPRENAMINGTYPE;
+
+/* State definitions for flag_CNFPROOFSTEPS */
+typedef enum { flag_CNFPROOFSTEPSMIN = 0,
+	       flag_CNFPROOFSTEPSMAX = INT_MAX
+} FLAG_CNFPROOFSTEPSTYPE;
+
+/* State definitions for flag_CNFRENAMING */
+typedef enum { flag_CNFRENAMINGMIN = -1,
+               flag_CNFRENAMINGOFF = flag_OFF,
+               flag_CNFRENAMINGON  = flag_ON,
+               flag_CNFRENAMINGMAX
+} FLAG_CNFRENAMINGTYPE;
+
+/* State definitions for flag_CNFSTRSKOLEM */
+typedef enum { flag_CNFSTRSKOLEMMIN = -1,
+               flag_CNFSTRSKOLEMOFF = flag_OFF,
+               flag_CNFSTRSKOLEMON  = flag_ON,
+               flag_CNFSTRSKOLEMMAX
+} FLAG_CNFSTRSKOLEMTYPE;
+
+/* State definitions for flag_DOCPROOF */
+typedef enum { flag_DOCPROOFMIN = -1,
+	       flag_DOCPROOFOFF = flag_OFF,
+	       flag_DOCPROOFON  = flag_ON,
+	       flag_DOCPROOFMAX
+} FLAG_DOCPROOFTYPE;
+
+/* State definitions for flag_DOCSPLIT */
+typedef enum { flag_DOCSPLITMIN = -1,
+	       flag_DOCSPLITOFF = flag_OFF,
+	       flag_DOCSPLITON  = flag_ON,
+	       flag_DOCSPLITMAX
+} FLAG_DOCSPLITTYPE;
+
+/* State definitions for flag_DOCSST */
+typedef enum { flag_DOCSSTMIN = -1,
+	       flag_DOCSSTOFF = flag_OFF,
+	       flag_DOCSSTON  = flag_ON,
+	       flag_DOCSSTMAX
+} FLAG_DOCSSTTYPE;
+
+/* State definitions for flag_FLOTTER */
+typedef enum { flag_FLOTTERMIN = -1,
+	       flag_FLOTTEROFF = flag_OFF,
+	       flag_FLOTTERON  = flag_ON,
+	       flag_FLOTTERMAX
+} FLAG_FLOTTERTYPE;
+
+/* State definitions for flag_FPDFGPROOF */
+typedef enum { flag_FPDFGPROOFMIN = -1,
+               flag_FPDFGPROOFOFF = flag_OFF,
+               flag_FPDFGPROOFON  = flag_ON,
+               flag_FPDFGPROOFMAX
+} FLAG_FPDFGPROOFTYPE;
+
+/* State definitions for flag_FPMODEL */
+typedef enum { flag_FPMODELMIN = -1,
+	       flag_FPMODELOFF = flag_OFF,
+	       flag_FPMODELALLCLAUSES,
+	       flag_FPMODELPOTENTIALLYPRODUCTIVECLAUSES,
+	       flag_FPMODELMAX
+} FLAG_FPMODELTYPE;
+
+/* State definitions for flag_FULLRED */
+typedef enum { flag_FULLREDMIN = -1,
+               flag_FULLREDOFF = flag_OFF,
+               flag_FULLREDON  = flag_ON,
+               flag_FULLREDMAX
+} FLAG_FULLREDTYPE;
+
+/* State definitions for flag_FUNCWEIGHT */
+typedef enum { flag_FUNCWEIGHTMIN = 0,
+	       flag_FUNCWEIGHTMAX = INT_MAX
+} FLAG_FUNCWEIGHTTYPE;
+
+/* State definitions for flag_IBUR */
+typedef enum { flag_BOUNDEDDEPTHUNITRESOLUTIONMIN = -1,
+               flag_BOUNDEDDEPTHUNITRESOLUTIONOFF = flag_OFF,
+               flag_BOUNDEDDEPTHUNITRESOLUTIONON  = flag_ON,
+               flag_BOUNDEDDEPTHUNITRESOLUTIONMAX
+} FLAG_IBURTYPE;
+
+/* State definitions for flag_IDEF */
+typedef enum { flag_DEFINITIONAPPLICATIONMIN = -1,
+               flag_DEFINITIONAPPLICATIONOFF = flag_OFF,
+               flag_DEFINITIONAPPLICATIONON  = flag_ON,
+               flag_DEFINITIONAPPLICATIONMAX
+} FLAG_IDEFTYPE;
+
+/* State definitions for flag_IEMS */
+typedef enum { flag_EMPTYSORTMIN = -1,
+               flag_EMPTYSORTOFF = flag_OFF,
+               flag_EMPTYSORTON  = flag_ON,
+               flag_EMPTYSORTMAX
+} FLAG_IEMSTYPE;
+
+/* State definitions for flag_IEQF */
+typedef enum { flag_EQUALITYFACTORINGMIN = -1,
+               flag_EQUALITYFACTORINGOFF = flag_OFF,
+               flag_EQUALITYFACTORINGON  = flag_ON,
+               flag_EQUALITYFACTORINGMAX
+} FLAG_IEQFTYPE;
+
+/* State definitions for flag_IEQR */
+typedef enum { flag_EQUALITYRESOLUTIONMIN = -1,
+               flag_EQUALITYRESOLUTIONOFF = flag_OFF,
+               flag_EQUALITYRESOLUTIONON  = flag_ON,
+               flag_EQUALITYRESOLUTIONMAX
+} FLAG_IEQRTYPE;
+
+/* State definitions for flag_IERR */
+typedef enum { flag_REFLEXIVITYRESOLUTIONMIN = -1,
+               flag_REFLEXIVITYRESOLUTIONOFF = flag_OFF,
+               flag_REFLEXIVITYRESOLUTIONON  = flag_ON,
+               flag_REFLEXIVITYRESOLUTIONMAX
+} FLAG_IERRTYPE;
+
+/* State definitions for flag_IMPM */
+typedef enum { flag_MERGINGPARAMODULATIONMIN = -1,
+               flag_MERGINGPARAMODULATIONOFF = flag_OFF,
+               flag_MERGINGPARAMODULATIONON  = flag_ON,
+               flag_MERGINGPARAMODULATIONMAX
+} FLAG_IMPMTYPE;
+
+/* State definitions for flag_INTERACTIVE */
+typedef enum { flag_INTERACTIVEMIN = -1,
+	       flag_INTERACTIVEOFF = flag_OFF,
+	       flag_INTERACTIVEON  = flag_ON,
+	       flag_INTERACTIVEMAX
+} FLAG_INTERACTIVETYPE;
+
+/* State definitions for flag_IOFC */
+typedef enum { flag_FACTORINGMIN = -1,
+	       flag_FACTORINGOFF = flag_OFF,
+	       flag_FACTORINGONLYRIGHT,
+	       flag_FACTORINGRIGHTANDLEFT,
+	       flag_FACTORINGMAX
+} FLAG_IOFCTYPE;
+
+/* State definitions for flag_IOHY */
+typedef enum { flag_ORDEREDHYPERRESOLUTIONMIN = -1,
+               flag_ORDEREDHYPERRESOLUTIONOFF = flag_OFF,
+               flag_ORDEREDHYPERRESOLUTIONON  = flag_ON,
+               flag_ORDEREDHYPERRESOLUTIONMAX
+} FLAG_IOHYTYPE;
+
+/* State definitions for flag_IOPM */
+typedef enum { flag_ORDEREDPARAMODULATIONMIN = -1,
+               flag_ORDEREDPARAMODULATIONOFF = flag_OFF,
+               flag_ORDEREDPARAMODULATIONON  = flag_ON,
+               flag_ORDEREDPARAMODULATIONMAX
+} FLAG_IOPMTYPE;
+
+/* State definitions for flag_IORE */
+typedef enum { flag_ORDEREDRESOLUTIONMIN = -1,
+	       flag_ORDEREDRESOLUTIONOFF = flag_OFF,
+	       flag_ORDEREDRESOLUTIONNOEQUATIONS,
+	       flag_ORDEREDRESOLUTIONWITHEQUATIONS,
+	       flag_ORDEREDRESOLUTIONMAX
+} FLAG_IORETYPE;
+
+/* State definitions for flag_ISFC */
+typedef enum { flag_STANDARDFACTORINGMIN = -1,
+	       flag_STANDARDFACTORINGOFF = flag_OFF,
+	       flag_STANDARDFACTORINGON  = flag_ON,
+	       flag_STANDARDFACTORINGMAX
+} FLAG_ISFCTYPE;
+
+/* State definitions for flag_ISHY */
+typedef enum { flag_STANDARDHYPERRESOLUTIONMIN = -1,
+               flag_STANDARDHYPERRESOLUTIONOFF = flag_OFF,
+               flag_STANDARDHYPERRESOLUTIONON  = flag_ON,
+               flag_STANDARDHYPERRESOLUTIONMAX
+} FLAG_ISHYTYPE;
+
+/* State definitions for flag_ISOR */
+typedef enum { flag_SORTRESOLUTIONMIN = -1,
+               flag_SORTRESOLUTIONOFF = flag_OFF,
+               flag_SORTRESOLUTIONON  = flag_ON,
+               flag_SORTRESOLUTIONMAX
+} FLAG_ISORTYPE;
+
+/* State definitions for flag_ISPL */
+typedef enum { flag_SUPERPOSITIONLEFTMIN = -1,
+               flag_SUPERPOSITIONLEFTOFF = flag_OFF,
+               flag_SUPERPOSITIONLEFTON  = flag_ON,
+               flag_SUPERPOSITIONLEFTMAX
+} FLAG_ISPLTYPE;
+
+/* State definitions for flag_ISPM */
+typedef enum { flag_STANDARDPARAMODULATIONMIN = -1,
+               flag_STANDARDPARAMODULATIONOFF = flag_OFF,
+               flag_STANDARDPARAMODULATIONON  = flag_ON,
+               flag_STANDARDPARAMODULATIONMAX
+} FLAG_ISPMTYPE;
+
+/* State definitions for flag_ISPR */
+typedef enum { flag_SUPERPOSITIONRIGHTMIN = -1,
+               flag_SUPERPOSITIONRIGHTOFF = flag_OFF,
+               flag_SUPERPOSITIONRIGHTON  = flag_ON,
+               flag_SUPERPOSITIONRIGHTMAX
+} FLAG_ISPRTYPE;
+
+/* State definitions for flag_ISRE */
+typedef enum { flag_STANDARDRESOLUTIONMIN = -1,
+	       flag_STANDARDRESOLUTIONOFF = flag_OFF,
+	       flag_STANDARDRESOLUTIONNOEQUATIONS,
+	       flag_STANDARDRESOLUTIONWITHEQUATIONS,
+	       flag_STANDARDRESOLUTIONMAX
+} FLAG_ISRETYPE;
+
+/* State definitions for flag_IUNR */
+typedef enum { flag_UNITRESOLUTIONMIN = -1,
+               flag_UNITRESOLUTIONOFF = flag_OFF,
+               flag_UNITRESOLUTIONON  = flag_ON,
+               flag_UNITRESOLUTIONMAX
+} FLAG_IUNRTYPE;
+
+/* State definitions for flag_IURR */
+typedef enum { flag_UNITRESULTINGRESOLUTIONMIN = -1,
+               flag_UNITRESULTINGRESOLUTIONOFF = flag_OFF,
+               flag_UNITRESULTINGRESOLUTIONON  = flag_ON,
+               flag_UNITRESULTINGRESOLUTIONMAX
+} FLAG_IURRTYPE;
+
+/* State definitions for flag_LOOPS */
+typedef enum { flag_LOOPSMIN = -2,
+	       flag_LOOPSUNLIMITED,
+	       flag_LOOPSMAX = INT_MAX
+} FLAG_LOOPSTYPE;
+
+/* State definitions for flag_MEMORY */
+typedef enum { flag_MEMORYMIN = -2,
+	       flag_MEMORYUNLIMITED,
+	       flag_MEMORYMAX = INT_MAX
+} FLAG_MEMORYTYPE;
+
+/* State definitions for flag_ORD */
+typedef enum { flag_ORDMIN = -1,
+	       flag_ORDKBO, 
+	       flag_ORDRPOS,
+	       flag_ORDMAX
+} FLAG_ORDTYPE;
+
+/* State definitions for flag_PAPPLYDEFS */
+typedef enum { flag_PAPPLYDEFSMIN = -1,
+               flag_PAPPLYDEFSOFF = flag_OFF,
+               flag_PAPPLYDEFSON  = flag_ON,
+               flag_PAPPLYDEFSMAX
+} FLAG_PAPPLYDEFSTYPE;
+
+/* State definitions for flag_PBDC */
+typedef enum { flag_PBDCMIN = -1,
+               flag_PBDCOFF = flag_OFF,
+               flag_PBDCON  = flag_ON,
+               flag_PBDCMAX
+} FLAG_PBDCTYPE;
+
+/* State definitions for flag_PBINC */
+typedef enum { flag_PBINCMIN = -1,
+               flag_PBINCOFF = flag_OFF,
+               flag_PBINCON  = flag_ON,
+               flag_PBINCMAX
+} FLAG_PBINCTYPE;
+
+/* State definitions for flag_PMRR */
+typedef enum { flag_PMRRMIN = -1,
+	       flag_PMRROFF = flag_OFF,
+	       flag_PMRRON  = flag_ON,
+	       flag_PMRRMAX
+} FLAG_PMRRTYPE;
+
+/* State definitions for flag_PCON */
+typedef enum { flag_PCONMIN = -1,
+	       flag_PCONOFF = flag_OFF,
+	       flag_PCONON  = flag_ON,
+	       flag_PCONMAX
+} FLAG_PCONTYPE;
+
+/* State definitions for flag_PDER */
+typedef enum { flag_PDERMIN = -1,
+	       flag_PDEROFF = flag_OFF,
+	       flag_PDERON  = flag_ON,
+	       flag_PDERMAX
+} FLAG_PDERTYPE;
+
+/* State definitions for flag_PEMPTYCLAUSE */
+typedef enum { flag_PEMPTYCLAUSEMIN = -1,
+	       flag_PEMPTYCLAUSEOFF = flag_OFF,
+	       flag_PEMPTYCLAUSEON  = flag_ON,
+	       flag_PEMPTYCLAUSEMAX
+} FLAG_PEMPTYCLAUSETYPE;
+
+/* State definitions for flag_PFLAGS */
+typedef enum { flag_PFLAGSMIN = -1,
+               flag_PFLAGSOFF = flag_OFF,
+               flag_PFLAGSON  = flag_ON,
+               flag_PFLAGSMAX
+} FLAG_PFLAGSTYPE;
+
+/* State definitions for flag_PGIVEN */
+typedef enum { flag_PGIVENMIN = -1,
+	       flag_PGIVENOFF = flag_OFF,
+	       flag_PGIVENON  = flag_ON,
+	       flag_PGIVENMAX
+} FLAG_PGIVENTYPE;
+
+/* State definitions for flag_PKEPT */
+typedef enum { flag_PKEPTMIN = -1,
+	       flag_PKEPTOFF = flag_OFF,
+	       flag_PKEPTON  = flag_ON,
+	       flag_PKEPTMAX
+} FLAG_PKEPTTYPE;
+
+/* State definitions for flag_PLABELS */
+typedef enum { flag_PLABELSMIN = -1,
+	       flag_PLABELSOFF = flag_OFF,
+	       flag_PLABELSON  = flag_ON,
+	       flag_PLABELSMAX
+} FLAG_PLABELSTYPE;
+
+/* State definitions for flag_POBV */
+typedef enum { flag_POBVMIN = -1,
+	       flag_POBVOFF = flag_OFF,
+	       flag_POBVON  = flag_ON,
+	       flag_POBVMAX
+} FLAG_POBVTYPE;
+
+/* State definitions for flag_POPTSKOLEM */
+typedef enum { flag_POPTSKOLEMMIN = -1,
+               flag_POPTSKOLEMOFF = flag_OFF,
+               flag_POPTSKOLEMON  = flag_ON,
+               flag_POPTSKOLEMMAX
+} FLAG_POPTSKOLEMTYPE;
+
+/* State definitions for flag_PPROBLEM */
+typedef enum { flag_PPROBLEMMIN = -1,
+	       flag_PPROBLEMOFF = flag_OFF,
+	       flag_PPROBLEMON  = flag_ON,
+	       flag_PPROBLEMMAX
+} FLAG_PPROBLEMTYPE;
+
+/* State definitions for flag_PREFCON */
+typedef enum { flag_PREFCONMIN = 0,
+	       flag_PREFCONUNCHANGED,
+	       flag_PREFCONMAX = INT_MAX
+} FLAG_PREFCONTYPE;
+
+/* State definitions for flag_PREFVAR */
+typedef enum { flag_PREFVARMIN = -1,
+               flag_PREFVAROFF = flag_OFF,
+               flag_PREFVARON  = flag_ON,
+               flag_PREFVARMAX
+} FLAG_PREFVARTYPE;
+
+/* State definitions for flag_PREW */
+typedef enum { flag_PREWMIN = -1,
+	       flag_PREWOFF = flag_OFF,
+	       flag_PREWON  = flag_ON,
+	       flag_PREWMAX
+} FLAG_PREWTYPE;
+
+/* State definitions for flag_PCRW */
+typedef enum { flag_PCRWMIN = -1,
+	       flag_PCRWOFF = flag_OFF,
+	       flag_PCRWON  = flag_ON,
+	       flag_PCRWMAX
+} FLAG_PCRWTYPE;
+
+/* State definitions for flag_PAED */
+typedef enum { flag_PAEDMIN = -1,
+	       flag_PAEDOFF = flag_OFF,
+	       flag_PAEDON  = flag_ON,
+	       flag_PAEDMAX
+} FLAG_PAEDTYPE;
+
+/* State definitions for flag_PSSI */
+typedef enum { flag_PSSIMIN = -1,
+	       flag_PSSIOFF = flag_OFF,
+	       flag_PSSION  = flag_ON,
+	       flag_PSSIMAX
+} FLAG_PSSITYPE;
+
+/* State definitions for flag_PSST */
+typedef enum { flag_PSSTMIN = -1,
+	       flag_PSSTOFF = flag_OFF,
+	       flag_PSSTON  = flag_ON,
+	       flag_PSSTMAX
+} FLAG_PSSTTYPE;
+
+/* State definitions for flag_PSTATISTIC */
+typedef enum { flag_PSTATISTICMIN = -1,
+               flag_PSTATISTICOFF = flag_OFF,
+               flag_PSTATISTICON  = flag_ON,
+               flag_PSTATISTICMAX
+} FLAG_PSTATISTICTYPE;
+
+/* State definitions for flag_PSTRSKOLEM */
+typedef enum { flag_PSTRSKOLEMMIN = -1,
+               flag_PSTRSKOLEMOFF = flag_OFF,
+               flag_PSTRSKOLEMON  = flag_ON,
+               flag_PSTRSKOLEMMAX
+} FLAG_PSTRSKOLEMTYPE;
+
+/* State definitions for flag_PSUB */
+typedef enum { flag_PSUBMIN = -1,
+	       flag_PSUBOFF = flag_OFF,
+	       flag_PSUBON  = flag_ON,
+	       flag_PSUBMAX
+} FLAG_PSUBTYPE;
+
+/* State definitions for flag_PTAUT */
+typedef enum { flag_PTAUTMIN = -1,
+	       flag_PTAUTOFF = flag_OFF,
+	       flag_PTAUTON  = flag_ON,
+	       flag_PTAUTMAX
+} FLAG_PTAUTTYPE;
+
+/* State definitions for flag_PUNC */
+typedef enum { flag_PUNCMIN = -1,
+	       flag_PUNCOFF = flag_OFF,
+	       flag_PUNCON  = flag_ON,
+	       flag_PUNCMAX
+} FLAG_PUNCTYPE;
+
+/* State definitions for flag_RBMRR */
+typedef enum { flag_RBMRRMIN = -1,
+               flag_RBMRROFF = flag_OFF,
+               flag_RBMRRON  = flag_ON,
+               flag_RBMRRMAX
+} FLAG_RBMRRTYPE;
+
+/* State definitions for flag_RBREW */
+typedef enum { flag_RBREWMIN = -1,
+               flag_RBREWOFF = flag_OFF,
+               flag_RBREWON  = flag_ON,
+               flag_RBREWMAX
+} FLAG_RBREWTYPE;
+
+/* State definitions for flag_RBCRW */
+typedef enum { flag_RBCRWMIN = -1,
+               flag_RBCRWOFF = flag_OFF,
+               flag_RBCRWON  = flag_ON,
+               flag_RBCRWMAX
+} FLAG_RBCRWTYPE;
+
+/* State definitions for flag_RBSUB */
+typedef enum { flag_RBSUBMIN = -1,
+               flag_RBSUBOFF = flag_OFF,
+               flag_RBSUBON  = flag_ON,
+               flag_RBSUBMAX
+} FLAG_RBSUBTYPE;
+
+/* State definitions for flag_RCON */
+typedef enum { flag_RCONMIN = -1,
+               flag_RCONOFF = flag_OFF,
+               flag_RCONON  = flag_ON,
+               flag_RCONMAX
+} FLAG_RCONTYPE;
+
+/* State definitions for flag_RFMRR */
+typedef enum { flag_RFMRRMIN = -1,
+               flag_RFMRROFF = flag_OFF,
+               flag_RFMRRON  = flag_ON,
+               flag_RFMRRMAX
+} FLAG_RFMRRTYPE;
+
+/* State definitions for flag_RFREW */
+typedef enum { flag_RFREWMIN = -1,
+               flag_RFREWOFF = flag_OFF,
+               flag_RFREWON  = flag_ON,
+               flag_RFREWMAX
+} FLAG_RFREWTYPE;
+
+/* State definitions for flag_RFCRW */
+typedef enum { flag_RFCRWMIN = -1,
+               flag_RFCRWOFF = flag_OFF,
+               flag_RFCRWON  = flag_ON,
+               flag_RFCRWMAX
+} FLAG_RFCRWTYPE;
+
+/* State definitions for flag_RFSUB */
+typedef enum { flag_RFSUBMIN = -1,
+               flag_RFSUBOFF = flag_OFF,
+               flag_RFSUBON  = flag_ON,
+               flag_RFSUBMAX
+} FLAG_RFSUBTYPE;
+
+/* State definitions for flag_RINPUT */
+typedef enum { flag_RINPUTMIN = -1,
+               flag_RINPUTOFF = flag_OFF,
+               flag_RINPUTON  = flag_ON,
+               flag_RINPUTMAX
+} FLAG_RINPUTTYPE;
+
+/* State definitions for flag_ROBV */
+typedef enum { flag_ROBVMIN = -1,
+               flag_ROBVOFF = flag_OFF,
+               flag_ROBVON  = flag_ON,
+               flag_ROBVMAX
+} FLAG_ROBVTYPE;
+
+/* State definitions for flag_RAED */
+typedef enum { flag_RAEDMIN = -1,
+	       flag_RAEDOFF = flag_OFF,
+	       flag_RAEDSOUND,
+	       flag_RAEDPOTUNSOUND,
+	       flag_RAEDMAX
+} FLAG_RAEDTYPE;
+
+/* State definitions for flag_RSSI */
+typedef enum { flag_RSSIMIN = -1,
+               flag_RSSIOFF = flag_OFF,
+               flag_RSSION  = flag_ON,
+               flag_RSSIMAX
+} FLAG_RSSITYPE;
+
+/* State definitions for flag_RSST */
+typedef enum { flag_RSSTMIN = -1,
+               flag_RSSTOFF = flag_OFF,
+               flag_RSSTON  = flag_ON,
+               flag_RSSTMAX
+} FLAG_RSSTTYPE;
+
+/* State definitions for flag_RTAUT */
+typedef enum { flag_RTAUTMIN = -1,
+	       flag_RTAUTOFF = flag_OFF,
+	       flag_RTAUTSYNTACTIC,
+	       flag_RTAUTSEMANTIC,
+	       flag_RTAUTMAX
+} FLAG_RTAUTTYPE;
+
+/* State definitions for flag_RTER */
+typedef enum { flag_RTERMIN = -1,
+	       flag_RTEROFF = flag_OFF,
+	       flag_RTERMAX = INT_MAX
+} FLAG_RTERTYPE;
+
+/* State definitions for flag_RUNC */
+typedef enum { flag_RUNCMIN = -1,
+               flag_RUNCOFF = flag_OFF,
+               flag_RUNCON  = flag_ON,
+               flag_RUNCMAX
+} FLAG_RUNCTYPE;
+
+/* State definitions for flag_SATINPUT */
+typedef enum { flag_SATINPUTMIN = -1,
+               flag_SATINPUTOFF = flag_OFF,
+               flag_SATINPUTON  = flag_ON,
+               flag_SATINPUTMAX
+} FLAG_SATINPUTTYPE;
+
+/* State definitions for flag_SELECT */
+typedef enum { flag_SELECTMIN = -1,
+	       flag_SELECTOFF = flag_OFF,
+	       flag_SELECTIFSEVERALMAXIMAL,
+	       flag_SELECTALWAYS,
+	       flag_SELECTMAX
+} FLAG_SELECTTYPE;
+
+/* State definitions for flag_SORTS */
+typedef enum { flag_SORTSMIN = -1,
+	       flag_SORTSOFF = flag_OFF,
+	       flag_SORTSMONADICWITHVARIABLE,
+	       flag_SORTSMONADICALL,
+	       flag_SORTSMAX
+} FLAG_SORTSTYPE;
+
+/* State definitions for flag_SOS */
+typedef enum { flag_SOSMIN = -1,
+	       flag_SOSOFF = flag_OFF,
+	       flag_SOSON  = flag_ON,
+	       flag_SOSMAX
+} FLAG_SOSTYPE;
+
+/* State definitions for flag_SPLITS */
+typedef enum { flag_SPLITSMIN = -2,
+	       flag_SPLITSUNLIMITED,
+	       flag_SPLITSOFF = flag_OFF,
+	       flag_SPLITSMAX = INT_MAX
+} FLAG_SPLITSTYPE;
+
+/* State definitions for flag_STDIN */
+typedef enum { flag_STDINMIN = -1,
+	       flag_STDINOFF = flag_OFF,
+	       flag_STDINON  = flag_ON,
+	       flag_STDINMAX
+} FLAG_STDINTYPE;
+
+/* State definitions for flag_TDFG2OTTEROPTIONS */
+typedef enum { flag_TDFG2OTTEROPTIONSMIN = -1,
+	       flag_TDFG2OTTEROPTIONSOFF = flag_OFF,
+	       flag_TDFG2OTTEROPTIONSPROOFCHECK,
+	       flag_TDFG2OTTEROPTIONSAUTO,
+	       flag_TDFG2OTTEROPTIONSAUTO2,
+	       flag_TDFG2OTTEROPTIONSMAX
+} FLAG_TDFG2OTTEROPTIONSTYPE;
+
+/* State definitions for flag_TIMELIMIT */
+typedef enum { flag_TIMELIMITMIN = -2,
+	       flag_TIMELIMITUNLIMITED,
+	       flag_TIMELIMITMAX = INT_MAX
+} FLAG_TIMELIMITTYPE;
+
+/* State definitions for flag_VARWEIGHT */
+typedef enum { flag_VARWEIGHTMIN = 0,
+	       flag_VARWEIGHTMAX = INT_MAX
+} FLAG_VARWEIGHTTYPE;
+
+/* State definitions for flag_WDRATIO */
+typedef enum { flag_WDRATIOMIN = 0,
+	       flag_WDRATIOMAX = INT_MAX
+} FLAG_WDRATIOTYPE;
+
+
+/* Define all flags */
+
+typedef enum { flag_AUTO, flag_STDIN, flag_INTERACTIVE, flag_FLOTTER,
+	       flag_SOS,
+
+               flag_SPLITS,     flag_MEMORY,     flag_TIMELIMIT,
+	       flag_DOCSST,     flag_DOCPROOF,
+	       flag_DOCSPLIT,   flag_LOOPS,      flag_PSUB,
+	       flag_PREW,       flag_PCRW,       flag_PCON,
+	       flag_PTAUT,      flag_POBV,       flag_PSSI,
+	       flag_PSST,       flag_PMRR,       flag_PUNC,
+	       flag_PAED,
+
+	       flag_PDER,       flag_PGIVEN,     flag_PLABELS,
+	       flag_PKEPT,      flag_PPROBLEM,   flag_PEMPTYCLAUSE,
+	       flag_PSTATISTIC, flag_FPMODEL,    flag_FPDFGPROOF,
+	       flag_PFLAGS,     flag_POPTSKOLEM, flag_PSTRSKOLEM,
+	       flag_PBDC,       flag_PBINC,
+	       flag_PAPPLYDEFS,
+
+	       flag_SELECT,     flag_RINPUT,     flag_SORTS,
+	       flag_SATINPUT,   flag_WDRATIO,    flag_PREFCON,
+	       flag_FULLRED,
+	       flag_FUNCWEIGHT, flag_VARWEIGHT,  flag_PREFVAR,
+	       flag_BOUNDMODE,  flag_BOUNDSTART, 
+	       flag_BOUNDLOOPS, flag_APPLYDEFS,
+
+	       flag_ORD,
+
+	       flag_CNFOPTSKOLEM, flag_CNFSTRSKOLEM, flag_CNFPROOFSTEPS,
+	       flag_CNFRENAMING,  flag_CNFPRENAMING, flag_CNFFEQREDUCTIONS,
+	       
+	       flag_IEMS,       flag_ISOR,
+	       flag_IEQR,       flag_IERR,
+	       flag_IEQF,       flag_IMPM,       flag_ISPR,
+	       flag_IOPM,       flag_ISPM,
+	       flag_ISPL,       flag_IORE,       flag_ISRE,
+	       flag_ISHY,       flag_IOHY,       flag_IURR,
+	       flag_IOFC,       flag_ISFC,
+	       flag_IUNR,       flag_IBUR,       flag_IDEF,
+
+	       flag_RFREW,      flag_RBREW,
+	       flag_RFCRW,      flag_RBCRW,
+	       flag_RFMRR,      flag_RBMRR,
+	       flag_ROBV,       flag_RUNC,       flag_RTER,
+	       flag_RTAUT,      flag_RSST,       flag_RSSI,
+	       flag_RFSUB,      flag_RBSUB,      flag_RAED,
+	       flag_RCON,       
+	       
+	       flag_TDFG2OTTEROPTIONS,
+
+	       flag_MAXFLAG } FLAG_ID;     /* flag_MAXFLAG is a final Dummy */
+
+
+/* Define different flag types */
+typedef enum { flag_INFERENCE,
+	       flag_PRINTING,
+	       flag_REDUCTION,
+	       flag_UNIQUE,               /* miscellaneous flags */
+	       flag_MAXTYPE
+} FLAG_TYPE;
+
+
+/* Define the flag data type */
+typedef int FLAG;
+
+/* Define the internal representation of a flag store */
+typedef FLAG FLAGARRAY[flag_MAXFLAG];
+
+/* Define the flag store */
+typedef FLAG *FLAGSTORE;
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+void        flag_Init(void);
+void        flag_InitFlotterFlags(FLAGSTORE, FLAGSTORE);
+void        flag_InitFlotterSubproofFlags(FLAGSTORE, FLAGSTORE);
+FLAGSTORE   flag_DefaultStore(void);
+void        flag_Print(FLAGSTORE);
+void        flag_FPrint(FILE*, FLAGSTORE);
+BOOL        flag_Lookup(const char*);
+FLAG_ID     flag_Id(const char*);
+const char* flag_Name(FLAG_ID);
+int         flag_Minimum(FLAG_ID);
+int         flag_Maximum(FLAG_ID);
+FLAG_TYPE   flag_Type(FLAG_ID Flag);
+void        flag_ClearInferenceRules(FLAGSTORE Store);
+void        flag_ClearReductionRules(FLAGSTORE Store);
+void        flag_ClearPrinting(FLAGSTORE Store);
+void        flag_SetReductionsToDefaults(FLAGSTORE Store);
+void        flag_CheckStore(FLAGSTORE Store);
+
+/**************************************************************/
+/* Macros                                                     */
+/**************************************************************/
+
+static __inline__ void flag_CheckFlagIdInRange(FLAG_ID FlagId)
+  /* prints an error report if a FLAG_ID is not valid */
+{
+#ifdef CHECK
+  if (FlagId >= flag_MAXFLAG) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In flag_CheckFlagIdInRange: Range of flags exceeded.");
+    misc_FinishErrorReport();
+  }
+#endif
+}
+
+static __inline__ void flag_CheckFlagValueInRange(FLAG_ID FlagId, int Value)
+  /* prints an error report if a flag's value is out of range */
+{
+  flag_CheckFlagIdInRange(FlagId);
+ 
+  if (Value <= flag_Minimum(FlagId)) {
+     misc_StartUserErrorReport();
+     misc_UserErrorReport("\n Error: Flag value %d is too small for flag %s.\n", Value, flag_Name(FlagId));
+     misc_FinishUserErrorReport();
+  }
+  else
+    if (Value >= flag_Maximum(FlagId)) {
+      misc_StartUserErrorReport();
+      misc_UserErrorReport("\n Error: Flag value %d is too large for flag %s.\n", Value, flag_Name(FlagId));
+      misc_FinishUserErrorReport();
+    }
+}
+
+static __inline__ void flag_CheckFlagTypeInRange(FLAG_TYPE Type)
+  /* prints an error report if a flag's type is out of range */
+{
+#ifdef CHECK
+  if (Type >= flag_MAXTYPE) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In flag_CheckFlagTypeInRange: Range of types exceeded.");
+    misc_FinishErrorReport();
+  }
+#endif
+}
+
+static __inline__ BOOL flag_StoreIsDefaultStore(FLAGSTORE Store)
+     /* returns TRUE if a flag store is the default store, FALSE otherwise */
+{
+  return (BOOL) (Store == flag_DefaultStore());
+}
+
+static __inline__ int flag_GetFlagValue(FLAGSTORE Store, FLAG_ID FlagId)
+{
+  int Value;
+
+  flag_CheckFlagIdInRange(FlagId);
+
+  Value = Store[FlagId];
+#ifdef CHECK
+  if (Value == flag_CLEAN) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In flag_GetFlagValue:");
+    misc_ErrorReport(" Attempt to read undefined flag value.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  return Value;
+}
+
+static __inline__ void flag_SetFlagValue(FLAGSTORE Store, FLAG_ID FlagId, int Value)
+{
+#ifdef CHECK
+  if (flag_StoreIsDefaultStore(Store)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In flag_SetFlagValue:");
+    misc_ErrorReport(" Attempt to modify default flag value.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  flag_CheckFlagIdInRange(FlagId);
+
+  flag_CheckFlagValueInRange (FlagId, Value);
+
+  Store[FlagId] = Value;
+}
+
+static __inline__ BOOL flag_ValueIsClean(FLAGSTORE Store, FLAG_ID FlagId)
+{
+#ifdef CHECK
+  flag_CheckFlagIdInRange(FlagId);
+  return (BOOL) (Store[FlagId] == flag_CLEAN);
+#else
+  return (BOOL) (flag_GetFlagValue(Store, FlagId) == flag_CLEAN);
+#endif
+}
+
+static __inline__ void flag_CleanStore(FLAGSTORE Store)
+{
+  int i;
+  for (i = 0; i < flag_MAXFLAG; i++)
+    Store[i] = flag_CLEAN;  
+}
+
+
+static __inline__ FLAGSTORE flag_CreateStore(void)
+     /* creates a fresh, clean FLAGSTORE */
+{
+  FLAGSTORE store;
+
+  store = (FLAGSTORE) memory_Malloc(sizeof(FLAGARRAY));
+  flag_CleanStore(store);
+  return store;
+}
+
+
+static __inline__ void flag_DeleteStore(FLAGSTORE Store)
+{
+#ifdef CHECK
+  /* Check if the flag store is a valid state */
+  flag_CheckStore(Store);
+#endif
+
+  memory_Free(Store,sizeof(FLAGARRAY));
+}
+
+
+static __inline__ void flag_InitStoreByDefaults(FLAGSTORE Store)
+{
+  FLAG_ID i;
+  for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i++)
+    flag_SetFlagValue(Store, i, flag_GetFlagValue(flag_DefaultStore(),i));  
+}
+
+
+static __inline__ void flag_SetFlagToDefault(FLAGSTORE Store, FLAG_ID Flag)
+{
+  flag_SetFlagValue(Store, Flag, flag_GetFlagValue(flag_DefaultStore(), Flag));
+}
+
+
+static __inline__ void flag_TransferFlag(FLAGSTORE Source, FLAGSTORE Destination, FLAG_ID FlagId)
+{
+  flag_SetFlagValue(Destination, FlagId, flag_GetFlagValue(Source, FlagId));
+}
+
+
+static __inline__ void flag_TransferAllFlags(FLAGSTORE Source, FLAGSTORE Destination)
+{
+  FLAG_ID i;
+  for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i++)
+    Destination[i] = Source[i];
+}
+
+
+static __inline__ void flag_TransferSetFlags(FLAGSTORE Source, FLAGSTORE Destination)
+{
+  FLAG_ID i;
+  for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i++)
+    if (!flag_ValueIsClean(Source,i))
+      flag_TransferFlag(Source, Destination, i);
+}
+
+
+static __inline__ BOOL flag_IsOfType(FLAG_ID Flag, FLAG_TYPE Type)
+/**************************************************************
+  INPUT:   A FlagId and a flag type.
+  RETURNS: TRUE is the flag is of given type,
+           FALSE otherwise.
+***************************************************************/
+{
+  flag_CheckFlagIdInRange(Flag);
+  flag_CheckFlagTypeInRange(Type);
+
+  return (BOOL) (flag_Type(Flag) == Type);
+}
+
+
+static __inline__ BOOL flag_IsInference(FLAG_ID Flag) 
+/**************************************************************
+  INPUT:   A FlagId.
+  RETURNS: TRUE is the flag is an inference flag,
+           FALSE otherwise.
+***************************************************************/
+{
+  flag_CheckFlagIdInRange(Flag);
+
+  return flag_IsOfType(Flag, flag_INFERENCE);
+}
+
+
+static __inline__ BOOL flag_IsReduction(FLAG_ID Flag) 
+/**************************************************************
+  INPUT:   A FlagId.
+  RETURNS: TRUE is the flag is a reduction flag,
+           FALSE otherwise.
+***************************************************************/
+{
+  flag_CheckFlagIdInRange(Flag);
+
+  return flag_IsOfType(Flag, flag_REDUCTION);
+}
+
+
+static __inline__ BOOL flag_IsPrinting(FLAG_ID Flag) 
+/**************************************************************
+  INPUT:   A FlagId.
+  RETURNS: TRUE is the flag is a printing flag,
+           FALSE otherwise.
+***************************************************************/
+{
+  flag_CheckFlagIdInRange(Flag);
+
+  return flag_IsOfType(Flag, flag_PRINTING);
+}
+
+
+static __inline__ BOOL flag_IsUnique(FLAG_ID Flag) 
+/**************************************************************
+  INPUT:   A FlagId.
+  RETURNS: TRUE is the flag is an unique flag,
+           FALSE otherwise.
+***************************************************************/
+{
+  flag_CheckFlagIdInRange(Flag);
+
+  return flag_IsOfType(Flag, flag_UNIQUE);
+}
+
+
+static __inline__ void flag_PrintReductionRules(FLAGSTORE Store)
+/**************************************************************
+  INPUT:   A FlagStore.
+  RETURNS: Nothing.
+  EFFECT:  Prints the values of all reduction flags to stdout.
+***************************************************************/
+{
+  FLAG_ID i;
+  fputs("\n Reductions: ", stdout);
+
+  for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i++) {
+    if (flag_IsReduction(i) && flag_GetFlagValue(Store, i))
+      printf("%s=%d ",flag_Name(i), flag_GetFlagValue(Store, i));
+  }
+}
+
+static __inline__ void flag_PrintInferenceRules(FLAGSTORE Store)
+/**************************************************************
+  INPUT:   A FlagStore.
+  RETURNS: Nothing.
+  EFFECT:  Prints the values of all inference flags to stdout.
+***************************************************************/
+{
+  FLAG_ID i;
+  fputs("\n Inferences: ", stdout);
+
+  for (i = (FLAG_ID) 0; i < flag_MAXFLAG; i++) {
+    if (flag_IsInference(i) && flag_GetFlagValue(Store, i))
+      printf("%s=%d ",flag_Name(i), flag_GetFlagValue(Store,i));
+  }
+}
+
+#endif
+
+
+
+
+
+
diff --git a/test/spass/foldfg.c b/test/spass/foldfg.c
new file mode 100644
index 0000000000000000000000000000000000000000..549b92e080d6c3fa0d7f33133b2a2dfb6c201ce5
--- /dev/null
+++ b/test/spass/foldfg.c
@@ -0,0 +1,2444 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *              FIRST ORDER LOGIC SYMBOLS                 * */
+/* *                                                        * */
+/* *  $Module:   FOL  DFG                                   * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#include "foldfg.h"
+#include "flags.h"
+
+
+SYMBOL  fol_ALL;
+SYMBOL  fol_EXIST;
+SYMBOL  fol_AND;
+SYMBOL  fol_OR;
+SYMBOL  fol_NOT;
+SYMBOL  fol_IMPLIES;
+SYMBOL  fol_IMPLIED;
+SYMBOL  fol_EQUIV;
+SYMBOL  fol_VARLIST;
+SYMBOL  fol_EQUALITY;
+SYMBOL  fol_TRUE;
+SYMBOL  fol_FALSE;
+
+LIST    fol_SYMBOLS;
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  FUNCTIONS                                             * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+void fol_Init(BOOL All, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A boolean value determining whether only 'equality' or
+           all fol symbols are created, and a precedence.
+  RETURNS: Nothing.
+  SUMMARY: Initializes the Fol Module.
+  EFFECTS: If <All> then all fol-symbols are created,
+           only 'equality' otherwise.
+	   The precedence of the first order logic symbols is set
+	   in <Precedence>.
+  CAUTION: MUST BE CALLED BEFORE ANY OTHER fol-FUNCTION.
+***************************************************************/
+{ 
+  if (All) {
+
+    fol_ALL      = symbol_CreateJunctor("forall", 2, symbol_STATLEX, Precedence);
+    fol_EXIST    = symbol_CreateJunctor("exists", 2, symbol_STATLEX, Precedence);
+    fol_AND      = symbol_CreateJunctor("and", symbol_ArbitraryArity(),
+					symbol_STATLEX, Precedence);
+    fol_OR       = symbol_CreateJunctor("or", symbol_ArbitraryArity(),
+					symbol_STATLEX, Precedence);
+    fol_NOT      = symbol_CreateJunctor("not", 1, symbol_STATLEX, Precedence);
+    fol_IMPLIES  = symbol_CreateJunctor("implies", 2, symbol_STATLEX, Precedence);
+    fol_IMPLIED  = symbol_CreateJunctor("implied", 2, symbol_STATLEX, Precedence);
+    fol_EQUIV    = symbol_CreateJunctor("equiv", 2, symbol_STATLEX, Precedence);
+    fol_VARLIST  = symbol_CreateJunctor("", symbol_ArbitraryArity(),
+					symbol_STATLEX, Precedence);
+    fol_EQUALITY = symbol_CreatePredicate("equal", 2, symbol_STATLEX, Precedence);
+    fol_TRUE     = symbol_CreatePredicate("true", 0, symbol_STATLEX, Precedence);
+    fol_FALSE    = symbol_CreatePredicate("false", 0, symbol_STATLEX, Precedence);
+
+    fol_SYMBOLS =
+      list_Cons((POINTER)fol_ALL, list_Cons((POINTER)fol_EXIST, 
+	list_Cons((POINTER)fol_AND, list_Cons((POINTER)fol_OR,
+	  list_Cons((POINTER)fol_NOT,
+	    list_Cons((POINTER)fol_IMPLIES, list_Cons((POINTER)fol_IMPLIED,
+              list_Cons((POINTER)fol_EQUIV, list_Cons((POINTER)fol_VARLIST,
+                list_Cons((POINTER)fol_EQUALITY, list_Cons((POINTER)fol_TRUE,
+		  list_List((POINTER)fol_FALSE))))))))))));
+  }
+  else {
+    fol_EQUALITY = symbol_CreatePredicate("equal", 2, symbol_STATLEX, Precedence);
+    fol_NOT      = symbol_CreateJunctor("not", 1, symbol_STATLEX, Precedence);
+    fol_SYMBOLS  = list_Cons((POINTER)fol_NOT, list_List((POINTER)fol_EQUALITY));
+  }
+}
+
+
+SYMBOL fol_IsStringPredefined(const char* String)
+/**************************************************************
+  INPUT:   A string.
+  RETURNS: The symbol iff String is a predefined fol string,
+           symbol NULL otherwise
+***************************************************************/
+{
+  LIST Scan;
+  for (Scan=fol_SYMBOLS; !list_Empty(Scan); Scan=list_Cdr(Scan))
+    if (string_Equal(String, symbol_Name((SYMBOL)list_Car(Scan))))
+      return (SYMBOL)list_Car(Scan);
+  return symbol_Null();
+}
+
+
+TERM fol_CreateQuantifier(SYMBOL Quantifier, LIST VarList, LIST Arguments)
+/**************************************************************
+  INPUT:   A symbol (which MUST be a fol quantifier),
+           a list of variables that will be bound, and
+           a list of arguments.
+  RETURNS: A quantified term.
+***************************************************************/
+{                                                                  
+#ifdef CHECK                                                          
+  if (!fol_IsQuantifier(Quantifier)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In fol_CreateQuantifier: Symbol isn't FOL quantifier.\n");
+    misc_FinishErrorReport();
+  }
+#endif                                                             
+                                                                   
+  return term_Create(Quantifier, list_Cons(term_Create(fol_Varlist(), VarList),
+					   Arguments));  
+}
+
+
+TERM fol_CreateQuantifierAddFather(SYMBOL Quantifier, LIST VarList, LIST Arguments)
+/**************************************************************
+  INPUT:   A symbol (which MUST be a fol quantifier),
+           a list of variables that will be bound, and
+           a list of arguments.
+	   In contrast to fol_CreateQuantifier the superterm members 
+	   are set for the arguments.
+  RETURNS: A quantified term.
+***************************************************************/
+{                                                                  
+  return term_CreateAddFather(Quantifier,                                
+			      list_Cons(term_CreateAddFather(fol_Varlist(), 
+							     VarList),   
+					Arguments));  
+}
+
+
+TERM fol_ComplementaryTerm(TERM Term)
+/**************************************************************
+  INPUT:   A formula.
+  RETURNS: The (copied) complementary (in sign) formula of <Term>
+***************************************************************/
+{
+  if (symbol_Equal(term_TopSymbol(Term), fol_Not()))
+    return term_Copy((TERM)list_First(term_ArgumentList(Term)));
+  else
+    return term_Create(fol_Not(), list_List(term_Copy(Term)));
+}
+
+
+LIST fol_GetNonFOLPredicates(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: The list of all predicate symbols except the predefined
+           FOL symbols.
+***************************************************************/
+{
+  LIST Result;
+
+  Result = symbol_GetAllPredicates();
+  Result = list_DeleteElementIf(Result, (BOOL (*)(POINTER))fol_IsPredefinedPred);
+  return Result;
+}
+
+
+LIST fol_GetAssignments(TERM Term)
+/**************************************************************
+  INPUT:   A formula.
+  RETURNS: All assignemnts that occur inside the formula, i.e.,
+           equations of the form "x=t" where "x" does not
+	   occur in "t".
+***************************************************************/
+{
+  if (term_IsAtom(Term)) {
+    if (fol_IsAssignment(Term))
+      return list_List(Term);
+  }
+  else
+    if (term_IsComplex(Term)) {
+      LIST Scan,Result;
+      Result = list_Nil();
+      for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+	Result = list_Nconc(fol_GetAssignments(list_Car(Scan)),Result);
+      return Result;
+    }
+
+  return list_Nil();
+  
+}
+
+static void fol_NormalizeVarsIntern(TERM Formula)
+/**************************************************************
+  INPUT:   A sentence.
+  RETURNS: void.
+  EFFECT:  The quantifier variables of the formula are
+           normalized, i.e., no two different quantifiers
+	   bind the same variable.
+  CAUTION: Desctructive.
+***************************************************************/
+{
+  SYMBOL   Top;
+  LIST     Scan1;
+  
+#ifdef CHECK
+  if (!term_IsTerm(Formula)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In fol_NormalizeVarsIntern: Formula is corrupted.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Top = term_TopSymbol(Formula);
+  
+  if (term_IsComplex(Formula)) {
+    if (fol_IsQuantifier(Top)) {
+      SYMBOL    Var;
+      LIST      OldVars,Scan2;
+      OldVars = list_Nil();
+      for (Scan1=fol_QuantifierVariables(Formula);!list_Empty(Scan1);Scan1=list_Cdr(Scan1)) {
+	Var     = term_TopSymbol(list_Car(Scan1));
+	OldVars = list_Nconc(OldVars,list_List((POINTER)term_BindingValue(Var)));
+	term_CreateValueBinding(Var, term_OldMark(), (POINTER)symbol_CreateStandardVariable());
+      }
+      fol_NormalizeVarsIntern(term_SecondArgument(Formula));
+      for (Scan1=fol_QuantifierVariables(Formula),Scan2=OldVars;
+	   !list_Empty(Scan1);
+	   Scan1=list_Cdr(Scan1),Scan2=list_Cdr(Scan2)) {
+	Var     = term_TopSymbol(list_Car(Scan1));
+	term_RplacTop(list_Car(Scan1),(SYMBOL)term_BindingValue(Var));
+	term_CreateValueBinding(Var, term_OldMark(), list_Car(Scan2));
+      }
+      list_Delete(OldVars);
+    }
+    else
+      for (Scan1=term_ArgumentList(Formula);!list_Empty(Scan1);Scan1=list_Cdr(Scan1))
+	fol_NormalizeVarsIntern(list_Car(Scan1));
+  }
+  else 
+    if (symbol_IsVariable(Top))
+      term_RplacTop(Formula,(SYMBOL)term_BindingValue(Top));
+
+  return;
+}
+
+
+void fol_NormalizeVars(TERM Formula)
+/**************************************************************
+  INPUT:   A sentence.
+  RETURNS: void.
+  EFFECT:  The quantifier variables of the formula are
+           normalized, i.e., no two different quantifiers
+	   bind the same variable.
+  CAUTION: Destructive.
+***************************************************************/
+{
+  symbol_ResetStandardVarCounter();
+  term_NewMark();
+  fol_NormalizeVarsIntern(Formula);
+}
+
+
+void fol_NormalizeVarsStartingAt(TERM Formula, SYMBOL S)
+/**************************************************************
+  INPUT:   A sentence.
+  RETURNS: void.
+  EFFECT:  The quantifier variables of the formula are
+           normalized, i.e., no two different quantifiers
+	   bind the same variable.
+  CAUTION: Destructive.
+***************************************************************/
+{
+  SYMBOL old = symbol_STANDARDVARCOUNTER;
+  symbol_SetStandardVarCounter(S);
+  term_NewMark();
+  fol_NormalizeVarsIntern(Formula);
+  symbol_SetStandardVarCounter(old);
+}
+
+
+void fol_RemoveImplied(TERM Formula)
+/*********************************************************
+  INPUT:   A formula.
+  RETURNS: void.
+  EFFECT:  All occurrences of "implied" are replaced by "implies"
+  CAUTION: Destructive.
+*******************************************************/
+{
+  if (!fol_IsLiteral(Formula)) {
+    if (fol_IsQuantifier(term_TopSymbol(Formula)))
+      fol_RemoveImplied(term_SecondArgument(Formula));
+    else {
+      LIST Scan;
+      if (symbol_Equal(term_TopSymbol(Formula),fol_Implied())) {
+	term_RplacTop(Formula,fol_Implies());
+	term_RplacArgumentList(Formula,list_NReverse(term_ArgumentList(Formula)));
+      }
+      for (Scan=term_ArgumentList(Formula);!list_Empty(Scan);Scan=list_Cdr(Scan))
+	fol_RemoveImplied(list_Car(Scan));
+    }
+  }
+}
+      
+
+BOOL fol_VarOccursFreely(TERM Var,TERM Term)
+/**************************************************************
+  INPUT:   A variable and a term.
+  RETURNS: TRUE iff <Var> occurs freely in <Term>
+***************************************************************/
+{ 
+  LIST    Scan;
+  int     Stack;
+  SYMBOL  Top;
+  BOOL    Hit;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term) || !term_IsVariable(Var)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In fol_VarOccursFreely: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Stack = stack_Bottom();
+
+  do {
+    Top = term_TopSymbol(Term);
+    if (term_IsComplex(Term)) {
+      if (fol_IsQuantifier(Top)) {
+	Hit = TRUE;
+	for (Scan=fol_QuantifierVariables(Term);!list_Empty(Scan)&&Hit;Scan=list_Cdr(Scan))
+	  if (symbol_Equal(term_TopSymbol(list_Car(Scan)),term_TopSymbol(Var)))
+	    Hit = FALSE;
+	if (Hit)
+	  stack_Push(list_Cdr(term_ArgumentList(Term)));
+      }
+      else
+	stack_Push(term_ArgumentList(Term));
+    }
+    else {
+      if (symbol_IsVariable(Top) && symbol_Equal(Top,term_TopSymbol(Var))) {
+	stack_SetBottom(Stack);
+	return TRUE;
+      }
+    }
+    while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+      stack_Pop();
+    if (!stack_Empty(Stack)) {
+      Term = (TERM)list_Car(stack_Top());
+      stack_RplacTop(list_Cdr(stack_Top()));
+    }
+  } while (!stack_Empty(Stack));
+
+  return FALSE;
+}
+
+
+LIST fol_FreeVariables(TERM Term)
+/**************************************************************
+  INPUT:   A term where we assume that no variable is bound by more than
+           one quantifier in <Term> !!!!!
+  RETURNS: The list of variables occurring in the term. Variables are
+           not (!) copied.
+           Note that there may be many terms with same variable symbol.
+	   All Variable terms are newly created.
+***************************************************************/
+{ 
+  LIST    Variables,Scan;
+  int     Stack;
+  SYMBOL  Top;
+  NAT     BoundMark,FreeMark;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term) || term_InBindingPhase()) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In fol_FreeVariables: Illegal input or context.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  term_StartBinding();
+
+  Variables  = list_Nil();
+  Stack      = stack_Bottom();
+  BoundMark  = term_ActMark();
+  FreeMark   = term_ActMark();
+
+  do {
+    Top = term_TopSymbol(Term);
+    if (term_IsComplex(Term)) {
+      if (fol_IsQuantifier(Top)) {
+	for (Scan=fol_QuantifierVariables(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+	  if (!term_VarIsMarked(term_TopSymbol(list_Car(Scan)), FreeMark))
+	    term_CreateBinding(term_TopSymbol(list_Car(Scan)), BoundMark);
+	stack_Push(term_ArgumentList(Term));                           /* Mark has to be removed ! */
+	stack_Push(list_Cdr(term_ArgumentList(Term)));
+      }
+      else
+	if (symbol_Equal(Top,fol_Varlist())) {
+	  for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+	    if (!term_VarIsMarked(term_TopSymbol(list_Car(Scan)), FreeMark))
+	      term_CreateBinding(term_TopSymbol(list_Car(Scan)), 0);  /* Mark has to be removed ! */
+	  stack_RplacTop(list_Cdr(stack_Top()));                   /* Second Argument is Quantifier Arg */
+	}
+	else
+	  stack_Push(term_ArgumentList(Term));
+    }
+    else {
+      if (symbol_IsVariable(Top) && !term_VarIsMarked(Top, FreeMark) 
+	  && !term_VarIsMarked(Top, BoundMark)) {
+	Variables = list_Cons(Term, Variables);
+	term_CreateBinding(Top, FreeMark);
+      }
+    }
+    while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+      stack_Pop();
+    if (!stack_Empty(Stack)) {
+      Term = (TERM)list_Car(stack_Top());
+      stack_RplacTop(list_Cdr(stack_Top()));
+    }
+  } while (!stack_Empty(Stack));
+
+  term_StopBinding();
+
+  return Variables;
+}
+
+LIST fol_BoundVariables(TERM Term)
+/**************************************************************
+  INPUT:   A term 
+  RETURNS: The list of bound variables occurring in the term.
+***************************************************************/
+{
+  int  stack;
+  LIST result;
+
+  stack  = stack_Bottom();
+  result = list_Nil();
+
+  do {
+    if (fol_IsQuantifier(term_TopSymbol(Term))) {
+      result = list_Nconc(result, list_Copy(fol_QuantifierVariables(Term))); 
+      stack_Push(list_Cdr(term_ArgumentList(Term)));
+    } 
+    else 
+      if (term_IsComplex(Term))
+	stack_Push(term_ArgumentList(Term));
+    
+    while (!stack_Empty(stack) && list_Empty(stack_Top()))
+      stack_Pop();
+
+    if (!stack_Empty(stack)) {
+      Term = list_Car(stack_Top());
+      stack_RplacTop(list_Cdr(stack_Top()));
+    }
+  } while (!stack_Empty(stack));
+  result = term_DeleteDuplicatesFromList(result);
+  return result;
+}
+
+
+void fol_Free(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: void.
+  EFFECT:  The memory used by the fol modul is freed.
+***************************************************************/
+{
+  list_Delete(fol_SYMBOLS);
+}
+
+
+BOOL fol_FormulaIsClause(TERM Formula)
+/**************************************************************
+  INPUT:   A formula.
+  RETURNS: TRUE, if <Formula> is a clause, FALSE otherwise.
+***************************************************************/
+{
+  LIST LitList;
+
+  if (term_TopSymbol(Formula) == fol_ALL)
+    Formula = term_SecondArgument(Formula);
+
+  if (term_TopSymbol(Formula) != fol_OR)
+    return FALSE;
+  
+  LitList = term_ArgumentList(Formula);
+
+  while (!list_Empty(LitList)) {
+    if (!fol_IsLiteral(list_Car(LitList)))
+      return FALSE;
+    LitList = list_Cdr(LitList);
+  }
+
+  return TRUE;
+}
+
+
+void fol_FPrintOtterOptions(FILE* File, BOOL Equality,
+			    FLAG_TDFG2OTTEROPTIONSTYPE Options)
+/**************************************************************
+  INPUT:   A file, a boolean flag and an Flag determining printed options.
+  RETURNS: Nothing.
+  SUMMARY: Prints Otter Options to <File>.
+           If <Equality> then appropriate paramodulation options
+	   are possibly added.
+***************************************************************/
+{
+  switch (Options) {
+  case flag_TDFG2OTTEROPTIONSPROOFCHECK:
+    fputs("\nset(process_input).", File);
+    fputs("\nset(binary_res).", File);
+    fputs("\nset(factor).", File);
+    /*fputs("\nassign(pick_given_ratio, 4).", File);*/
+    fputs("\nclear(print_kept).", File);
+    fputs("\nassign(max_seconds, 20).", File);
+    if (Equality) {
+      fputs("\nclear(print_new_demod).", File);
+      fputs("\nclear(print_back_demod).", File);
+      fputs("\nclear(print_back_sub).", File);
+      /*fputs("\nset(knuth_bendix).", File);*/
+      fputs("\nset(para_from).", File);
+      fputs("\nset(para_into).", File);
+      fputs("\nset(para_from_vars).", File);
+      fputs("\nset(back_demod).", File);    
+    } /* No break: add auto */
+  case flag_TDFG2OTTEROPTIONSAUTO:
+    fputs("\nset(auto).", File);
+    break;
+  case flag_TDFG2OTTEROPTIONSAUTO2:
+    fputs("\nset(auto2).", File);
+    break;
+  case flag_TDFG2OTTEROPTIONSOFF:
+     /* print nothing */
+    break;
+  default:
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In fol_FPrintOtterOptions: Illegal parameter value %d.",
+		     Options);
+    misc_FinishErrorReport();
+  }
+
+  fputs("\n\n",File);
+}
+
+static void fol_FPrintOtterFormula(FILE* File, TERM Formula)
+/**************************************************************
+  INPUT:   A file and a formula.
+  RETURNS: Nothing.
+  SUMMARY: Prints the formula in Otter format to <File>. 
+***************************************************************/
+{
+  SYMBOL Top;
+
+  Top = term_TopSymbol(Formula);
+
+  if (symbol_IsPredicate(Top)) {
+    if (symbol_Equal(Top, fol_Equality())) {
+      term_FPrintOtterPrefix(File,term_FirstArgument(Formula));
+      fputs(" = ", File);
+      term_FPrintOtterPrefix(File,term_SecondArgument(Formula));
+    }
+    else
+      term_FPrintOtterPrefix(File,Formula);
+  }
+  else {
+    if (fol_IsQuantifier(Top)) {
+      LIST Scan;
+      for (Scan=fol_QuantifierVariables(Formula);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+	if (symbol_Equal(Top,fol_All()))
+	  fputs("all ", File);
+	else
+	  fputs("exists ", File);
+	term_FPrintOtterPrefix(File, list_Car(Scan));
+	fputs(" (", File);
+      }
+      fol_FPrintOtterFormula(File, term_SecondArgument(Formula));
+      for (Scan=fol_QuantifierVariables(Formula);!list_Empty(Scan);Scan=list_Cdr(Scan))
+	fputs(")", File);
+    }
+    else
+      if (symbol_Equal(Top,fol_Not())) {
+	fputs("- (", File);
+	fol_FPrintOtterFormula(File, term_FirstArgument(Formula));
+	fputs(")", File);
+      }
+      else
+	if (symbol_Equal(Top, fol_And()) || symbol_Equal(Top, fol_Or()) || 
+	    symbol_Equal(Top, fol_Equiv()) || symbol_Equal(Top, fol_Implies()) ) {
+	  LIST Scan;
+	  fputs("(", File);
+	  for (Scan=term_ArgumentList(Formula);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+	    if (fol_IsLiteral(list_Car(Scan)))
+	      fol_FPrintOtterFormula(File, list_Car(Scan));
+	    else {
+	      fputs("(", File);
+	      fol_FPrintOtterFormula(File, list_Car(Scan));
+	      fputs(")", File);
+	    }
+	    if (!list_Empty(list_Cdr(Scan))) {
+	      if (symbol_Equal(Top, fol_And()))
+		fputs(" & ", File);
+	      if (symbol_Equal(Top, fol_Or()))
+		fputs(" | ", File);
+	      if (symbol_Equal(Top, fol_Equiv()))
+		fputs(" <-> ", File);
+	      if (symbol_Equal(Top, fol_Implies()))
+		fputs(" -> ", File);
+	    }
+	  }
+	  fputs(")", File);
+	}
+  }
+}
+
+void fol_FPrintOtter(FILE* File, LIST Formulae, FLAG_TDFG2OTTEROPTIONSTYPE Option)
+/**************************************************************
+  INPUT:   A file, a list of pairs (label.formula) and an option flag.
+  RETURNS: Nothing.
+  SUMMARY: Prints a  the respective formulae in Otter format to <File>. 
+***************************************************************/
+{
+  LIST   Scan;
+  BOOL   Equality;
+  TERM   Formula;
+
+  Equality = FALSE;
+
+  for (Scan=Formulae;!list_Empty(Scan) && !Equality; Scan=list_Cdr(Scan)) {
+    Formula  = (TERM)list_PairSecond(list_Car(Scan));
+    Equality = term_ContainsSymbol(Formula, fol_Equality());
+  }
+
+  fol_FPrintOtterOptions(File, Equality, Option);
+
+  if (!list_Empty(Formulae)) {
+    fputs("formula_list(usable).\n", File);
+    if (Equality)
+      fputs("all x (x=x).\n", File);
+    for (Scan=Formulae;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+      if (list_PairFirst(list_Car(Scan)) != NULL)
+	fprintf(File,"\n%% %s \n",(char *)list_PairFirst(list_Car(Scan)));
+      fol_FPrintOtterFormula(File,list_PairSecond(list_Car(Scan)));
+      fputs(".\n\n", File);
+    }
+    fputs("end_of_list.\n\n", File);
+  }
+}
+
+
+void fol_FPrintDFGSignature(FILE* File)
+/**************************************************************
+  INPUT:   A file stream.
+  RETURNS: Nothing.
+  SUMMARY: Prints all signature symbols in DFG format to the
+           file stream.
+***************************************************************/
+
+{
+  NAT    i;
+  SYMBOL symbol;
+  LIST   functions, predicates;
+
+  functions  = symbol_GetAllFunctions();
+  predicates = fol_GetNonFOLPredicates();
+
+  /* First print the function symbols */
+  if (!list_Empty(functions)) {
+    fputs("  functions[", File);
+    i = 0;
+    do {
+      symbol = (SYMBOL) list_Top(functions);
+      fprintf(File, "(%s, %d)", symbol_Name(symbol), symbol_Arity(symbol));
+      functions = list_Pop(functions);
+      if (!list_Empty(functions))
+	fputs(", ", File);
+      if (i < 15)
+	i++;
+      else {
+	i = 0;
+	fputs("\n\t", File);
+      }
+      
+    } while (!list_Empty(functions));
+    fputs("].\n", File);
+  }
+
+  /* Now print the predicate symbols */
+  if (!list_Empty(predicates)) {
+    i = 0;
+    fputs("  predicates[", File);
+    do {
+      symbol = (SYMBOL) list_Top(predicates);
+      fprintf(File, "(%s, %d)", symbol_Name(symbol), symbol_Arity(symbol));
+      predicates = list_Pop(predicates);
+      if (!list_Empty(predicates))
+	fputs(", ", File);
+      if (i < 15)
+	i++;
+      else {
+	i = 0;
+	fputs("\n\t", File);
+      }
+    } while (!list_Empty(predicates));
+    fputs("].\n", File);
+  }
+  list_Delete(predicates);
+  list_Delete(functions);
+}
+
+
+static void fol_TermListFPrintDFG(FILE* File, LIST List)
+/**************************************************************
+  INPUT:   A list of terms.
+  RETURNS: Nothing.
+***************************************************************/
+{
+  for (; !list_Empty(List); List=list_Cdr(List)) {
+    fol_FPrintDFG(File,list_Car(List));
+    if (!list_Empty(list_Cdr(List)))
+      putc(',', File);
+  }
+}
+
+
+void fol_FPrintDFG(FILE* File, TERM Term)
+/**************************************************************
+  INPUT:   A file and a term.
+  RETURNS: none.
+  SUMMARY: Prints the term in prefix notation to the file. 
+  CAUTION: Uses the other fol_Output functions.
+***************************************************************/
+{
+  if (term_IsComplex(Term)) {
+    if (fol_IsQuantifier(term_TopSymbol(Term))) {
+      symbol_FPrint(File,term_TopSymbol(Term));
+      fputs("([", File);
+      fol_TermListFPrintDFG(File,fol_QuantifierVariables(Term));
+      fputs("],", File);
+      fol_FPrintDFG(File, term_SecondArgument(Term));
+      putc(')', File);
+    }
+    else {
+      symbol_FPrint(File,term_TopSymbol(Term));
+      putc('(', File);
+      fol_TermListFPrintDFG(File,term_ArgumentList(Term));
+      putc(')', File);
+    }
+  }
+  else 
+    symbol_FPrint(File,term_TopSymbol(Term));
+}
+
+void fol_PrintDFG(TERM Term)
+{
+  fol_FPrintDFG(stdout,Term);
+}
+
+
+void fol_PrintPrecedence(PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A precedence.
+  RETURNS: void
+  EFFECT:  Prints the current precedence to stdout,
+           fol symbols are excluded.
+***************************************************************/
+{
+  if (symbol_SignatureExists()) {
+    LIST      Symbols, Scan;
+    SYMBOL    Symbol;
+    int       Index;
+    SIGNATURE S;
+
+    Symbols = list_Nil();
+    for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+      S = symbol_Signature(Index);
+      if (S != NULL) {
+	Symbol = S->info;
+	if  ((symbol_IsPredicate(Symbol) || symbol_IsFunction(Symbol)) &&
+	     !fol_IsPredefinedPred(Symbol))
+	  Symbols = list_Cons((POINTER)Symbol, Symbols);
+      }
+    }
+    Symbols = symbol_SortByPrecedence(Symbols, Precedence);
+    for (Scan = Symbols; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+      S = symbol_Signature(symbol_Index((SYMBOL)list_Car(Scan)));
+      fputs(S->name, stdout);
+      if (!list_Empty(list_Cdr(Scan)))
+	fputs(" > ", stdout);
+    }
+    list_Delete(Symbols);
+  }
+}
+
+void fol_FPrintPrecedence(FILE *File, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A file to print to, and a precedence.
+  RETURNS: Nothing.
+  EFFECT:  Prints the current precedence as a setting 
+           command in DFG syntax to <File>.
+	   fol symbols are excluded.
+***************************************************************/
+{
+  if (symbol_SignatureExists()) {
+    LIST      Symbols, Scan;
+    SYMBOL    Symbol;
+    int       Index;
+    SIGNATURE S;
+
+    Symbols = list_Nil();
+    for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+      S = symbol_Signature(Index);
+      if (S != NULL) {
+	Symbol = S->info;
+	if ((symbol_IsPredicate(Symbol) || symbol_IsFunction(Symbol)) &&
+	    !fol_IsPredefinedPred(Symbol))
+	  Symbols = list_Cons((POINTER)Symbol, Symbols);
+      }
+    }
+    Symbols = symbol_SortByPrecedence(Symbols, Precedence);
+    Index   = 0;
+    fputs("set_precedence(", File);
+    for (Scan = Symbols; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+      S = symbol_Signature(symbol_Index((SYMBOL)list_Car(Scan)));
+      putc('(', File);
+      fputs(S->name, File);
+      putc(',', File);
+      fprintf(File, "%d", S->weight);
+      putc(',', File);
+      putc((symbol_HasProperty((SYMBOL)list_Car(Scan),ORDRIGHT) ? 'r' :
+	    (symbol_HasProperty((SYMBOL)list_Car(Scan),ORDMUL) ? 'm' : 'l')),
+	   File);
+      putc(')', File);
+      if (!list_Empty(list_Cdr(Scan)))
+	putc(',', File);
+
+      if (Index > 15) {
+	Index = 0;
+	fputs("\n\t", File);
+      }
+      else
+	Index++;
+    }
+    fputs(").", File);
+    list_Delete(Symbols);
+  }
+}
+
+
+static void fol_FPrintFormulaList(FILE* File, LIST Formulas, const char* Name)
+/**************************************************************
+  INPUT:   A file, a list of formulas, a name.
+  EFFECTS: Print a list formulas in DFG format, with given list name.
+ **************************************************************/
+{
+  LIST scan;
+
+  fputs("list_of_formulae(", File);
+  fputs(Name, File);
+  fputs(").\n", File);
+  for (scan = Formulas; !list_Empty(scan); scan= list_Cdr(scan)) {
+    fputs("\tformula(", File);
+    fol_FPrintDFG(File, list_Car(scan));
+    fputs(").\n", File);
+  }
+  fputs("end_of_list.\n\n", File);
+}
+
+
+void fol_FPrintDFGProblem(FILE* File, const char* Name, const char* Author, 
+			  const char* Status, const char* Description, 
+			  LIST Axioms, LIST Conjectures)
+/**************************************************************
+  INPUT:   A file, two lists of formulas, ??? EK
+  EFFECTS: Prints a complete DFG file containing these lists.
+**************************************************************/
+{
+  fputs("begin_problem(Unknown).\n\n", File);
+
+  fputs("list_of_descriptions.\n", File);
+  fprintf(File,"name(%s).\n",Name);
+  fprintf(File,"author(%s).\n",Author);
+  fprintf(File,"status(%s).\n",Status);
+  fprintf(File,"description(%s).\n",Description);
+  fputs("end_of_list.\n\n", File);
+  
+  fputs("list_of_symbols.\n", File);
+  fol_FPrintDFGSignature(File);
+  fputs("end_of_list.\n\n", File);
+
+  fol_FPrintFormulaList(File, Axioms, "axioms");
+  fol_FPrintFormulaList(File, Conjectures, "conjectures");
+
+  fputs("end_problem.\n", File);
+}
+
+
+BOOL fol_AssocEquation(TERM Term, SYMBOL *Result)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: TRUE if the term is an equation defining associativity
+           for some function symbol.
+  EFFECT:  If the <Term> is an assoc equation, then <*Result> is
+           assigned the assoc symbol.
+***************************************************************/
+{
+  
+  if (fol_IsEquality(Term)) {
+    SYMBOL Top;
+    TERM   Left,Right;
+    Left = term_FirstArgument(Term);
+    Right= term_SecondArgument(Term);
+    Top  = term_TopSymbol(Left);
+    if (symbol_IsFunction(Top) && symbol_Arity(Top) == 2 && 
+	symbol_Equal(Top,term_TopSymbol(Right))) {
+      SYMBOL v1,v2,v3;
+      if (term_IsVariable(term_FirstArgument(Left)))
+	v1 = term_TopSymbol(term_FirstArgument(Left));
+      else
+	if (term_IsVariable(term_FirstArgument(Right))) {
+	  Term  = Right;
+	  Right = Left;
+	  Left  = Term;
+	  v1 = term_TopSymbol(term_FirstArgument(Left));
+	}
+	else
+	  return FALSE;
+      if (symbol_Equal(term_TopSymbol(term_SecondArgument(Left)),Top) &&
+	  symbol_IsVariable((v2=term_TopSymbol(term_FirstArgument(term_SecondArgument(Left)))))&&
+	  symbol_IsVariable((v3=term_TopSymbol(term_SecondArgument(term_SecondArgument(Left)))))&&
+	  symbol_Equal(term_TopSymbol(term_FirstArgument(Right)),Top) &&
+	  symbol_Equal(v1,term_TopSymbol(term_FirstArgument(term_FirstArgument(Right)))) &&
+	  symbol_Equal(v2,term_TopSymbol(term_SecondArgument(term_FirstArgument(Right)))) &&
+	  symbol_Equal(v3,term_TopSymbol(term_SecondArgument(Right)))) {
+	*Result = Top;
+	return TRUE;
+      }
+    }
+  }
+
+  return FALSE;
+}
+
+
+BOOL fol_DistributiveEquation(TERM Term, SYMBOL* Addition,
+			      SYMBOL* Multiplication)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: TRUE if the term is an equation defining distributivity
+           for two function symbols, FALSE otherwise.
+  EFFECT:  If the function returns TRUE, < Addition> and
+           <Multiplication> return the respective symbols.
+***************************************************************/
+{
+  TERM left, right, help, v1, v2, v3;
+
+  if (!fol_IsEquality(Term))
+    return FALSE;
+
+  left  = term_FirstArgument(Term);
+  right = term_SecondArgument(Term);
+  
+  if (term_EqualTopSymbols(left, right) ||
+      !symbol_IsFunction(term_TopSymbol(left)) ||
+      !symbol_IsFunction(term_TopSymbol(right)) ||
+      symbol_Arity(term_TopSymbol(left)) != 2 ||
+      symbol_Arity(term_TopSymbol(right)) != 2)
+    return FALSE;
+  
+  if (term_IsVariable(term_FirstArgument(left)))
+    v1 = term_FirstArgument(left);
+  else if (term_IsVariable(term_FirstArgument(right))) {
+    help  = right;   /* Exchange left and right terms */
+    right = left;
+    left  = help;
+    v1 = term_FirstArgument(left);
+  } else
+    return FALSE;
+
+  if (!term_EqualTopSymbols(left, term_FirstArgument(right)) ||
+      !term_EqualTopSymbols(left, term_SecondArgument(right)) ||
+      !term_EqualTopSymbols(term_SecondArgument(left), right))
+    return FALSE;
+
+  v2 = term_FirstArgument(term_SecondArgument(left));
+  v3 = term_SecondArgument(term_SecondArgument(left));
+
+  if (term_IsVariable(v2) && term_IsVariable(v3) &&
+      term_EqualTopSymbols(term_FirstArgument(term_FirstArgument(right)), v1) &&
+      term_EqualTopSymbols(term_SecondArgument(term_FirstArgument(right)), v2) &&
+      term_EqualTopSymbols(term_FirstArgument(term_SecondArgument(right)), v1) &&
+      term_EqualTopSymbols(term_SecondArgument(term_SecondArgument(right)), v3)) {
+    *Addition       = term_TopSymbol(right);
+    *Multiplication = term_TopSymbol(left);
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+
+static LIST fol_InstancesIntern(TERM Formula, TERM ToMatch, NAT Symbols)
+/**************************************************************
+  INPUT:   A formula in which all instances of <ToMatch> are searched.
+	   The number of symbols of <ToMatch>.
+  RETURNS: The list of found instances.
+  CAUTION: Bound variables must be different, for otherwise the
+           used matching produces wrong results!!
+***************************************************************/
+{
+  NAT  HitSymbols;
+  LIST Result;
+  int  Stack;
+  
+  Stack  = stack_Bottom();
+  Result = list_Nil();
+
+  do {    
+    HitSymbols = term_Size(Formula);    /* First check number of symbols of current formula */
+
+    if (HitSymbols >= Symbols && (Formula != ToMatch)) {
+      cont_StartBinding();
+      if (unify_MatchFlexible(cont_LeftContext(), ToMatch, Formula))
+	Result = list_Cons(Formula, Result);
+      else 
+	if (!symbol_IsPredicate(term_TopSymbol(Formula))) {
+	  if (fol_IsQuantifier(term_TopSymbol(Formula)))
+	    stack_Push(list_Cdr(term_ArgumentList(Formula)));
+	  else
+	    stack_Push(term_ArgumentList(Formula));
+	}
+      cont_BackTrack();
+    }
+    
+    while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+      stack_Pop();
+    if (!stack_Empty(Stack)) {
+      Formula = (TERM)list_Car(stack_Top());
+      stack_RplacTop(list_Cdr(stack_Top()));
+    }
+  } while (!stack_Empty(Stack));
+  
+  return Result;
+}
+ 
+   
+LIST fol_Instances(TERM Formula, TERM ToMatch)
+/**************************************************************
+  INPUT:   A formula in which all instances of <ToMatch> are searched.
+  RETURNS: The list of found occurrences matched by <ToMatch>.
+           The formula <ToMatch> is not included!
+***************************************************************/
+{
+  NAT Symbols;
+  
+  Symbols = term_ComputeSize(ToMatch); /* We use the number of symbols as a filter */
+  term_InstallSize(Formula);
+
+  return fol_InstancesIntern(Formula, ToMatch, Symbols);
+}
+
+
+static LIST fol_GeneralizationsIntern(TERM Formula, TERM MatchedBy, NAT Symbols)
+/**************************************************************
+  INPUT:   A formula in which all instances of <ToMatch> are searched.
+	   The number of symbols of <ToMatch>.
+  RETURNS: The list of found instances.
+  CAUTION: Bound variables must be different, for otherwise the
+           used matching produces wrong results!!
+***************************************************************/
+{
+  NAT  HitSymbols;
+  LIST Result;
+  int  Stack;
+  
+  Stack  = stack_Bottom();
+  Result = list_Nil();
+
+  do {    
+    if (Formula != MatchedBy) {
+      HitSymbols = term_Size(Formula);    /* First check number of symbols of current formula */
+      if (HitSymbols <= Symbols) {
+	cont_StartBinding();
+	if (unify_MatchFlexible(cont_LeftContext(), Formula, MatchedBy))
+	  Result = list_Cons(Formula, Result);
+	else 
+	  if (!symbol_IsPredicate(term_TopSymbol(Formula))) {
+	    if (fol_IsQuantifier(term_TopSymbol(Formula)))
+	      stack_Push(list_Cdr(term_ArgumentList(Formula)));
+	    else
+	      stack_Push(term_ArgumentList(Formula));
+	  }
+	cont_BackTrack();
+      }
+      else
+	if (!symbol_IsPredicate(term_TopSymbol(Formula))) {
+	  if (fol_IsQuantifier(term_TopSymbol(Formula)))
+	    stack_Push(list_Cdr(term_ArgumentList(Formula)));
+	  else
+	    stack_Push(term_ArgumentList(Formula));
+	}
+    }
+    
+    while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+      stack_Pop();
+    if (!stack_Empty(Stack)) {
+      Formula = (TERM)list_Car(stack_Top());
+      stack_RplacTop(list_Cdr(stack_Top()));
+    }
+  } while (!stack_Empty(Stack));
+  
+  return Result;
+}
+
+
+LIST fol_Generalizations(TERM Formula, TERM MatchedBy)
+/**************************************************************
+  INPUT:   A formula in which all first-order generalizations of <MatchedBy> are searched.
+  RETURNS: The list of found occurrences that are more general than <MatchedBy>.
+           The formula <MatchedBy> is not included!
+***************************************************************/
+{
+  NAT Symbols;
+  
+  Symbols = term_ComputeSize(MatchedBy); /* We use the number of symbols as a filter */
+  term_InstallSize(Formula);
+
+  return fol_GeneralizationsIntern(Formula, MatchedBy, Symbols);
+}
+
+
+TERM fol_MostGeneralFormula(LIST Formulas)
+/**************************************************************
+  INPUT:   A list of formulas.
+  RETURNS: A most general formula out of the list, i.e., if
+           some formula is returned, there is no formula in the
+	   list that is more general than that formula.
+***************************************************************/
+{
+  TERM Result, Candidate;
+  LIST Scan;
+
+#ifdef CHECK
+  if (list_Empty(Formulas)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In fol_MostGeneralFormula: Called with empty list.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Result = list_Car(Formulas);
+
+  for (Scan=list_Cdr(Formulas);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Candidate = (TERM)list_Car(Scan);
+    cont_StartBinding();
+    if (unify_MatchFlexible(cont_LeftContext(), Candidate, Result))
+      Result = Candidate;
+    cont_BackTrack();
+  }
+
+  return Result;
+}
+
+
+void fol_ReplaceVariable(TERM Term, SYMBOL Symbol, TERM Repl)
+/**************************************************************
+  INPUT:   A term, a variable symbol and a replacement term.
+  RETURNS: void
+  EFFECT:  All free variables with <Symbol> in <Term> are replaced with copies of <Repl>
+  CAUTION: Destructive
+***************************************************************/
+{
+  LIST Scan;
+
+#ifdef CHECK
+  if (!(term_IsTerm(Term) && term_IsTerm(Repl) && symbol_IsVariable(Symbol))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In fol_ReplaceVariable: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (fol_IsQuantifier(term_TopSymbol(Term))) {
+    for (Scan=term_ArgumentList(term_FirstArgument(Term)); !list_Empty(Scan); Scan=list_Cdr(Scan))
+      if (symbol_Equal(term_TopSymbol(list_Car(Scan)), Symbol)) /* var is bound */
+	return;
+    fol_ReplaceVariable(term_SecondArgument(Term), Symbol, Repl);
+  }
+    
+  if (symbol_Equal(term_TopSymbol(Term), Symbol)) {
+    term_RplacTop(Term,term_TopSymbol(Repl));
+    term_RplacArgumentList(Term,term_CopyTermList(term_ArgumentList(Repl)));
+  } 
+  else 
+    for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+      fol_ReplaceVariable(list_Car(Scan),Symbol,Repl);
+}
+
+
+static void fol_PrettyPrintInternDFG(TERM Term, int Depth)
+/**************************************************************
+  INPUT:   A term and a depth parameter for indentation.
+  RETURNS: none.
+  SUMMARY: Prints the term hopefully more pretty to stdout.
+***************************************************************/
+{
+  int     i;
+  LIST   scan;
+  SYMBOL Top;
+
+  Top = term_TopSymbol(Term);
+  if (!symbol_Equal(Top,fol_Varlist())) {
+    for (i = 0; i < Depth; i++) 
+      fputs("  ", stdout);
+    if (fol_IsLiteral(Term))
+      term_PrintPrefix(Term);
+    else {
+      if (symbol_IsJunctor(Top)) {
+	if (term_IsComplex(Term)) {
+	  symbol_Print(Top);
+	  putchar('(');
+	  if (!fol_IsQuantifier(Top))
+	    putchar('\n');
+	  for (scan=term_ArgumentList(Term); !list_Empty(scan); scan= list_Cdr(scan)) {
+	    fol_PrettyPrintInternDFG((TERM) list_Car(scan), Depth+1);
+	    if (!list_Empty(list_Cdr(scan)))
+	      fputs(",\n", stdout);
+	  }
+	  putchar(')');
+	}
+	else {
+	  if (term_IsVariable(Term)) {
+	    symbol_Print(Top);
+	  }
+	  else {
+	    putchar('(');
+	    symbol_Print(Top);
+	    putchar(')');
+	  }
+	}
+      }
+      else {
+	term_PrintPrefix(Term);
+      }
+    }
+  }
+  else {
+    putchar('[');
+    term_TermListPrintPrefix(term_ArgumentList(Term));
+    putchar(']');
+  }  
+}
+
+
+void fol_PrettyPrintDFG(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: none.
+  SUMMARY: Prints the term hopefully more pretty to stdout. 
+***************************************************************/
+{
+  fol_PrettyPrintInternDFG(Term, 0);
+}
+
+
+TERM fol_CheckFatherLinksIntern(TERM Term) 
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: A subterm whose superterm pointer is not set correctly,
+           else NULL.
+  SUMMARY: Checks if all superterm links except of those from quantifier
+           variables are set correctly.
+***************************************************************/ 
+{
+  LIST l;
+  if (fol_IsQuantifier(term_TopSymbol(Term)))
+    return fol_CheckFatherLinksIntern(term_SecondArgument(Term));
+  if (term_IsComplex(Term)) {
+    for (l=term_ArgumentList(Term); !list_Empty(l); l=list_Cdr(l)) {
+      TERM result;
+      if (term_Superterm((TERM) list_Car(l)) != Term)
+	return (TERM) list_Car(l);
+      result = fol_CheckFatherLinksIntern((TERM) list_Car(l));
+      if (result != NULL)
+	return result;
+    }
+  }
+  return NULL;
+}
+
+
+void fol_CheckFatherLinks(TERM Term) 
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: none.
+  SUMMARY: Checks if all superterm links except of those from
+           quantifier variables are set correctly.
+***************************************************************/ 
+{
+  TERM Result;
+
+  Result = fol_CheckFatherLinksIntern(Term);
+#ifdef CHECK
+  if (Result != NULL || term_Superterm(Term) != NULL) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In fol_CheckFatherLinks:");
+    misc_ErrorReport(" Found a term where the father links");
+    misc_ErrorReport(" are not correctly set.");
+    misc_FinishErrorReport();    
+  }
+#endif
+}
+
+
+static void fol_PrettyPrintIntern(TERM Term, int Depth)
+/**************************************************************
+  INPUT:   A term and a depth parameter for indentation.
+  RETURNS: none.
+  SUMMARY: Prints the term hopefully more pretty to stdout.
+***************************************************************/
+{
+  int i;
+  LIST scan;
+
+  for (i = 0; i < Depth; i++) 
+    fputs("  ", stdout);
+  if (symbol_IsJunctor(term_TopSymbol(Term))) {
+    if (term_IsComplex(Term)) {
+      if (fol_IsQuantifier(term_TopSymbol(Term))) {
+	symbol_Print(term_TopSymbol(Term));
+	fputs("([", stdout);
+	for (scan=fol_QuantifierVariables(Term); !list_Empty(scan); scan=list_Cdr(scan)) {
+	  symbol_Print(term_TopSymbol((TERM) list_Car(scan)));
+	  if (!list_Empty(list_Cdr(scan)))
+	    putchar(',');
+	}
+	fputs("],\n", stdout);
+	fol_PrettyPrintIntern(term_SecondArgument(Term), Depth+1);
+      }
+      else {
+	symbol_Print(term_TopSymbol(Term));
+	fputs("(\n", stdout);
+	for (scan=term_ArgumentList(Term); !list_Empty(scan); scan= list_Cdr(scan)) {
+	  fol_PrettyPrintIntern((TERM) list_Car(scan), Depth+1);
+	  if (!list_Empty(list_Cdr(scan)))
+	    fputs(",\n", stdout);
+	}
+	putchar(')');
+      }
+    }
+    else {
+      if (term_IsVariable(Term)) {
+	symbol_Print(term_TopSymbol(Term));
+      }
+      else {
+	putchar('(');
+	symbol_Print(term_TopSymbol(Term));
+	putchar(')');
+      }
+    }
+  }
+  else {
+    term_PrintPrefix(Term);
+  }
+}
+
+
+void fol_PrettyPrint(TERM Term)  
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: none.
+  SUMMARY: Prints the term hopefully more pretty to stdout. 
+***************************************************************/
+{
+  fol_PrettyPrintIntern(Term, 0);
+}
+
+
+LIST fol_GetSubstEquations(TERM Term)
+/**************************************************************
+  INPUT:   A Term.
+  RETURNS: The list of all equations of the form x=t or t=x in <Term>
+           where x is a variable and t is a term not containing x.
+***************************************************************/
+{
+  LIST Result;
+  LIST Scan;
+
+  Result = list_Nil();
+
+  if (fol_IsQuantifier(term_TopSymbol(Term)))
+    return fol_GetSubstEquations(term_SecondArgument(Term));
+  if (fol_IsEquality(Term)) {
+    if (term_IsVariable(term_SecondArgument(Term))) {
+      if (!term_ContainsSymbol(term_FirstArgument(Term), term_TopSymbol(term_SecondArgument(Term))))
+	Result = list_Cons(Term, Result);
+    }
+    else {
+      if (term_IsVariable(term_FirstArgument(Term)))
+	if (!term_ContainsSymbol(term_SecondArgument(Term), term_TopSymbol(term_FirstArgument(Term))))
+	  Result = list_Cons(Term, Result);
+    }
+  }
+  if (symbol_IsPredicate(term_TopSymbol(Term)))
+    return Result;
+  else 
+    for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+      Result = list_Nconc(Result, fol_GetSubstEquations(list_Car(Scan)));
+
+  return Result;
+}
+
+
+TERM fol_GetBindingQuantifier(TERM Term, SYMBOL Symbol)
+/**************************************************************
+  INPUT:   A symbol and a term containing the symbol.
+  RETURNS: The Quantifier binding the symbol.
+***************************************************************/
+{ 
+  LIST Scan;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term) || !symbol_IsSymbol(Symbol)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In fol_GetBindingQuantifier: Illegal input.\n");
+    misc_FinishErrorReport();    
+  }
+#endif
+
+  if (fol_IsQuantifier(term_TopSymbol(Term))) {
+    for ( Scan = fol_QuantifierVariables(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+      if (symbol_Equal(Symbol, term_TopSymbol(list_Car(Scan)))) {
+	return Term;
+      }
+  }
+
+  return fol_GetBindingQuantifier(term_Superterm(Term), Symbol);
+}
+
+
+int fol_TermPolarity(TERM SubTerm, TERM Term)
+/**************************************************************
+  INPUT:   Two terms, SubTerm subterm of Term.
+           It is assumed that the superterm links in <Term>
+	   are established.
+  RETURNS: The polarity of SubTerm in Term.
+***************************************************************/
+{
+  TERM SuperTerm;
+
+#ifdef CHECK
+  if (!term_IsTerm(SubTerm) || !term_IsTerm(Term) || !term_FatherLinksEstablished(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In fol_TermPolarity: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (SubTerm == Term)
+    return 1;
+  
+  SuperTerm = term_Superterm(SubTerm);
+
+  if (SuperTerm) {
+    SYMBOL Top;
+    Top = term_TopSymbol(SuperTerm);
+
+    if (symbol_Equal(Top,fol_AND) || symbol_Equal(Top,fol_OR) || fol_IsQuantifier(Top))
+      return fol_TermPolarity(SuperTerm, Term);
+
+    if (symbol_Equal(Top,fol_NOT))
+      return (-fol_TermPolarity(SuperTerm, Term));
+
+    if (symbol_Equal(Top,fol_EQUIV))
+      return 0;
+
+    if (symbol_Equal(Top, fol_IMPLIES)) { 
+      if (SubTerm == term_FirstArgument(SuperTerm))
+	return (-fol_TermPolarity(SuperTerm, Term));
+      else
+	return fol_TermPolarity(SuperTerm, Term);
+    }
+    if (symbol_Equal(Top, fol_IMPLIED)) {
+      if (SubTerm == term_SecondArgument(SuperTerm))
+	return (-fol_TermPolarity(SuperTerm, Term));
+      else 
+	return  fol_TermPolarity(SuperTerm, Term);
+    }
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In fol_TermPolarity: Unknown first-order operator.\n");
+    misc_FinishErrorReport();
+  }
+
+  return 1;
+}
+
+
+static int fol_PolarCheckCount(TERM Nowterm, TERM SuperTerm, int Nowpolar)
+/**************************************************************
+   INPUT:   Two terms, Nowterm and its superterm, and the polarity of 
+            Nowterm.
+   RETURNS: The polarity of SuperTerm according to Nowterm.
+   COMMENT: Helpfunction for fol_PolarCheck.
+***************************************************************/
+{ 
+  SYMBOL Top;
+  Top = term_TopSymbol(SuperTerm);
+
+  if (Nowterm == SuperTerm)
+    return Nowpolar;
+
+  if (symbol_Equal(Top, fol_OR) || symbol_Equal(Top, fol_AND) || fol_IsQuantifier(Top) ||
+      (symbol_Equal(Top, fol_IMPLIES) && Nowterm == term_SecondArgument(SuperTerm)) ||
+      (symbol_Equal(Top, fol_IMPLIED) && Nowterm == term_FirstArgument(SuperTerm)))
+    return Nowpolar;
+
+  if (symbol_Equal(term_TopSymbol(SuperTerm), fol_EQUIV))
+    return 0;
+
+  return -Nowpolar;
+}
+
+
+static BOOL fol_PolarCheckAllquantor(TERM Subterm, TERM Term, int SubtermPolar)
+/**************************************************************
+   INPUT:   Two terms, Subterm subterm of Term, and polarity of Subterm.
+   RETURNS: TRUE iff Subterm occurs in Term disjunctively.
+   COMMENT: Help function for fol_PolarCheck. Dual case to Exist quantor.
+***************************************************************/
+{
+  TERM    SuperTerm;
+  SYMBOL  Top;
+  int     SubPolar;
+
+  if (Subterm == Term)  
+    return TRUE;
+
+  SuperTerm  = term_Superterm(Subterm);
+
+  if (SuperTerm == Term)  /* Ugly, but it does not make sense to introduce a further function */
+    return TRUE;
+
+  Top        = term_TopSymbol(SuperTerm);
+  SubPolar   = fol_PolarCheckCount(Subterm, SuperTerm, SubtermPolar);
+
+  /* To be clarified: can the below condition generalized to universal quantifiers? */
+
+  if (symbol_Equal(Top,fol_NOT) ||                   
+     (symbol_Equal(Top, fol_OR) && SubPolar == 1) ||
+     (symbol_Equal(Top, fol_AND) && SubPolar == -1) ||
+     (symbol_Equal(Top,fol_IMPLIES) && SubPolar == 1) ||
+     (symbol_Equal(Top,fol_IMPLIED) && SubPolar == 1))
+    return fol_PolarCheckAllquantor(SuperTerm, Term, SubPolar);
+
+  return FALSE;
+}
+
+
+static BOOL fol_PolarCheckExquantor(TERM Subterm, TERM Term, int SubtermPolar)
+/**************************************************************
+  INPUT:   Two terms, Subterm subterm of Term, and polarity of Subterm.
+  RETURNS: TRUE iff Subterm occurs in Term conjunctively.
+  COMMENT: Help function for fol_PolarCheck. Dual case to Allquantor.
+***************************************************************/
+{
+  TERM    SuperTerm;
+  SYMBOL  Top;
+  int     SubPolar;
+
+  if (Subterm == Term)  
+    return TRUE;
+
+  SuperTerm  = term_Superterm(Subterm);
+
+  if (SuperTerm == Term)  /* Ugly, but it does not make sense to introduce a further function */
+    return TRUE;
+
+  Top        = term_TopSymbol(SuperTerm);
+  SubPolar   = fol_PolarCheckCount(Subterm, SuperTerm, SubtermPolar);
+
+  /* To be clarified: can the below condition generalized to existential quantifiers? */
+
+  if (symbol_Equal(Top,fol_NOT) ||
+      (symbol_Equal(Top, fol_OR) && SubPolar == -1) ||
+      (symbol_Equal(Top, fol_AND) && SubPolar == 1) ||
+      (symbol_Equal(Top,fol_IMPLIES) && SubPolar == -1) ||
+      (symbol_Equal(Top,fol_IMPLIED) && SubPolar == -1))
+    return fol_PolarCheckExquantor(SuperTerm, Term, SubPolar);
+
+  return FALSE;
+}
+
+BOOL fol_PolarCheck(TERM Subterm, TERM Term)
+/**************************************************************
+  INPUT:   Two terms, <Subterm> is of the form x=t, where x or t variable. 
+           <Subterm> is a subterm of <Term> and the top symbol of
+	   <Term> must be the binding quantifier of x or t.
+  RETURNS: BOOL if check is ok.
+***************************************************************/
+{
+  int SubtermPolar;
+  SYMBOL Top;
+
+  SubtermPolar = fol_TermPolarity(Subterm, Term);
+  Top          = term_TopSymbol(Term);
+
+  if (SubtermPolar == -1 && symbol_Equal(Top, fol_ALL))
+    return fol_PolarCheckAllquantor(Subterm, Term, SubtermPolar);
+
+  if (SubtermPolar == 1 && symbol_Equal(Top, fol_EXIST))
+    return fol_PolarCheckExquantor(Subterm, Term, SubtermPolar);
+
+  return FALSE;
+}
+
+
+void fol_PopQuantifier(TERM Term) 
+/**************************************************************
+  INPUT:   A term whose top symbol is a quantifier.
+  RETURNS: Nothing.
+  EFFECT:  Removes the quantifier.
+           If supertermlinks were set, they are updated.
+***************************************************************/
+{
+  TERM SubTerm;
+  LIST Scan;
+
+#ifdef CHECK
+  if (!fol_IsQuantifier(term_TopSymbol(Term))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In fol_PopQuantifier: Top symbol of term isn't a quantifier.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  term_Delete(term_FirstArgument(Term));
+  SubTerm = term_SecondArgument(Term);
+  list_Delete(term_ArgumentList(Term));
+  term_RplacTop(Term,term_TopSymbol(SubTerm));
+  term_RplacArgumentList(Term,term_ArgumentList(SubTerm));
+  for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+    if (term_Superterm(list_Car(Scan)))
+      term_RplacSuperterm(list_Car(Scan),Term);
+  term_Free(SubTerm);
+}
+
+
+void fol_DeleteQuantifierVariable(TERM Quant,SYMBOL Var)
+/****************************************************************
+  INPUT:   A term starting with a quantifier and a variable symbol.
+  RETURNS: Nothing.
+  EFFECT:  The variable is deleted from the list of variables
+           bound by the quantor of <Quant>
+*****************************************************************/
+{
+  LIST Scan;
+
+  for (Scan=fol_QuantifierVariables(Quant);!list_Empty(Scan);Scan=list_Cdr(Scan))
+    if (symbol_Equal(term_TopSymbol(list_Car(Scan)), Var)) {
+      term_Delete((TERM)list_Car(Scan));
+      list_Rplaca(Scan, (POINTER)NULL);
+    }
+  term_RplacArgumentList(term_FirstArgument(Quant),
+			 list_PointerDeleteElement(fol_QuantifierVariables(Quant),(POINTER)NULL));
+  if (list_Empty(fol_QuantifierVariables(Quant)))
+    fol_PopQuantifier(Quant);
+}
+
+
+
+void fol_SetTrue(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: Nothing.
+  EFFECT:  Replaces Term destructively by fol_True().
+***************************************************************/
+{
+  term_DeleteTermList(term_ArgumentList(Term));
+  term_RplacArgumentList(Term, list_Nil());
+  term_RplacTop(Term, fol_True());
+}
+
+void fol_SetFalse(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: Nothing.
+  EFFECT:  Replaces Term destructively by fol_False().
+***************************************************************/
+{
+  term_DeleteTermList(term_ArgumentList(Term));
+  term_RplacArgumentList(Term, list_Nil());
+  term_RplacTop(Term, fol_False());
+}
+
+
+static void fol_ReplaceByArgCon(TERM Term)
+/**************************************************************
+  INPUT:   A term of the form f(...)=f(...), where f is a function.
+  RETURNS: True.
+  EFFECT:  Substitutes Term by <and(t1=s1, t2=s2, ..., tn=sn)>,
+           where ti and si are the arguments of both f's in Term.
+***************************************************************/
+{
+  LIST Scan, Bscan, List, Hlist;
+  TERM Func1, Func2, NewTerm;
+
+  Func1 = term_FirstArgument(Term);
+  Func2 = term_SecondArgument(Term);
+  List  = term_ArgumentList(Term);
+  Scan  = list_Nil();
+  term_RplacArgumentList(Term, list_Nil());
+  term_RplacTop(Term, fol_And());
+
+  for (Scan = term_ArgumentList(Func1),Bscan = term_ArgumentList(Func2);
+       !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    Hlist = list_Nil();
+    Hlist = list_Cons(list_Car(Bscan), Hlist);
+    Hlist = list_Cons(list_Car(Scan), Hlist);
+    NewTerm = term_Create(fol_Equality(), Hlist);
+    term_RplacArgumentList(Term, list_Cons(NewTerm, term_ArgumentList(Term)));
+    Bscan = list_Cdr(Bscan);
+  }
+
+  list_Delete(term_ArgumentList(Func1));
+  list_Delete(term_ArgumentList(Func2));
+  term_RplacArgumentList(Func1, list_Nil());
+  term_RplacArgumentList(Func2, list_Nil());
+  term_Delete(Func1);
+  term_Delete(Func2);
+  list_Delete(List);
+}
+
+
+BOOL fol_PropagateFreeness(TERM Term)
+/**************************************************************
+  INPUT:   A term and a list of functions.
+  RETURNS: True iff a subterm of the form f(...)=f(...) occurs in the term,
+           where f has property FREELY and GENERATED.
+  EFFECT:  Substitutes all occurences of f=f by <and(t1=s1,...tn=sn)>,where
+           ti and si are the arguments of each f in f=f. 
+***************************************************************/
+{
+  BOOL    Free;
+  LIST    Scan;
+  TERM    Argum1, Argum2;
+
+  Free = FALSE;
+
+  if (fol_IsQuantifier(term_TopSymbol(Term)))
+    return fol_PropagateFreeness(term_SecondArgument(Term));
+
+  if (!term_IsAtom(Term)) {
+    for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+      if (fol_PropagateFreeness(list_Car(Scan)))
+	Free = TRUE;
+  }
+  else
+    if (fol_IsEquality(Term)) {
+      Argum1 = term_FirstArgument(Term);
+      Argum2 = term_SecondArgument(Term);
+      if (symbol_Equal(term_TopSymbol(Argum1), term_TopSymbol(Argum2)) &&
+	  symbol_HasProperty(term_TopSymbol(Argum1), FREELY) &&
+	  symbol_HasProperty(term_TopSymbol(Argum1), GENERATED)) {
+	fol_ReplaceByArgCon(Term);
+	return TRUE;
+      }
+    }
+
+  return Free;
+}
+
+
+static BOOL fol_PropagateWitnessIntern(TERM Equation, SYMBOL Variable)
+/**************************************************************
+  INPUT:   A Term which is an equation where <Variable> is one
+           of the equation's arguments that does not occur in the
+           other argument. Father links must exist.
+  RETURNS: True in case of witness propagation.
+  EFFECT:  Checks whether subterm the equation is part of
+           is of the form described in fol_PropagateWitness and
+           substitutes in case of a hit.
+***************************************************************/
+{
+  TERM    SuperTerm, BindQuantor, Predicat;
+  SYMBOL  SuperTop;
+
+  SuperTerm   = term_Superterm(Equation);  
+  
+  if (SuperTerm == term_Null())
+    return FALSE;
+
+  SuperTop    = term_TopSymbol(SuperTerm);
+  BindQuantor = term_Superterm(SuperTerm);
+
+  if (BindQuantor == term_Null())
+    return FALSE;
+
+  if (!fol_IsQuantifier(term_TopSymbol(BindQuantor)) ||
+      list_Length(term_ArgumentList(SuperTerm)) != 2)
+    return FALSE;
+
+  if (Equation == term_SecondArgument(SuperTerm)) 
+    Predicat  = term_FirstArgument(SuperTerm);
+  else 
+    Predicat = term_SecondArgument(SuperTerm);
+
+  if (symbol_Equal(term_TopSymbol(BindQuantor), fol_All()) &&
+      symbol_Equal(SuperTop, fol_Or()) &&
+      symbol_Equal(term_TopSymbol(Predicat), fol_Not()) &&
+      symbol_HasProperty(term_TopSymbol(term_FirstArgument(Predicat)), FREELY) && 
+      symbol_HasProperty(term_TopSymbol(term_FirstArgument(Predicat)), GENERATED) &&
+      symbol_Equal(term_TopSymbol(term_FirstArgument(term_FirstArgument(Predicat))), Variable)) {
+    fol_SetFalse(BindQuantor);
+    return TRUE;
+  }
+  if (!symbol_HasProperty(term_TopSymbol(Predicat), FREELY)    ||
+      !symbol_HasProperty(term_TopSymbol(Predicat), GENERATED) ||
+      !symbol_Equal(Variable, term_TopSymbol(term_FirstArgument(Predicat))))
+    return FALSE;
+
+  if (symbol_Equal(term_TopSymbol(BindQuantor), fol_All())) {
+    if (symbol_Equal(SuperTop, fol_Implies()) && 
+	term_SecondArgument(SuperTerm) == Equation) {
+      fol_SetFalse(BindQuantor);
+      return TRUE;
+    }
+    if (symbol_Equal(SuperTop, fol_Implied()) &&
+	term_FirstArgument(SuperTerm) == Equation) {
+      fol_SetFalse(BindQuantor);
+      return TRUE;
+    }
+  }
+  else /* Exquantor */
+    if (symbol_Equal(SuperTop, fol_And())) {
+      fol_SetTrue(BindQuantor);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+
+BOOL fol_PropagateWitness(TERM Term)
+/**************************************************************
+  INPUT:   A Term.
+  RETURNS: True in case of witness propagation.
+  EFFECT:  Substitutes any subterm of Term of the form
+             forall([x],implies(P(x),x=t))
+             forall([x],implied(x=t,P(x)))
+             forall([x],or(notP(x),x=t))   by FALSE  and
+             exists([x],and(P(x),x=t))     by TRUE,  where
+           P has property FREELY and GENERATED, x doesn't occur in t.
+***************************************************************/
+{
+  BOOL Hit;
+  LIST Scan;
+
+  Hit = FALSE;
+
+  if (fol_IsQuantifier(term_TopSymbol(Term)))
+    return fol_PropagateWitness(term_SecondArgument(Term));
+  if (fol_IsEquality(Term)) {
+    if (term_IsVariable(term_SecondArgument(Term))) {
+      if (!term_ContainsSymbol(term_FirstArgument(Term), term_TopSymbol(term_SecondArgument(Term))))
+        Hit = fol_PropagateWitnessIntern(Term,term_TopSymbol(term_SecondArgument(Term)));
+    }
+    else {
+      if (term_IsVariable(term_FirstArgument(Term)))
+	if (!term_ContainsSymbol(term_SecondArgument(Term), term_TopSymbol(term_FirstArgument(Term))))
+	  Hit = fol_PropagateWitnessIntern(Term,term_TopSymbol(term_FirstArgument(Term)));
+    }
+  }
+  if (symbol_IsPredicate(term_TopSymbol(Term)))
+    return FALSE;
+
+  for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+    if (fol_PropagateWitness(list_Car(Scan)))
+      Hit = TRUE;
+
+  return Hit;
+}
+
+BOOL fol_PropagateTautologies(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: True iff function replaced a subterm.
+  EFFECT:  Replaces all occurences of t=t, or(A,not(A)) by TRUE
+           and and(A,not(A)) by FALSE.
+***************************************************************/
+{
+  BOOL    Hit;
+  LIST    Scan, Bscan, ArgumentList;
+  SYMBOL  Top;
+
+  Top          = term_TopSymbol(Term);
+  Hit          = FALSE;
+  ArgumentList = term_ArgumentList(Term);
+
+  if (fol_IsQuantifier(Top))
+    return fol_PropagateTautologies(term_SecondArgument(Term));
+
+  if (fol_IsEquality(Term)) {
+    if (term_Equal(term_FirstArgument(Term), term_SecondArgument(Term))) {
+      fol_SetTrue(Term);
+      return TRUE;
+    }
+  }
+
+  if (symbol_Equal(Top, fol_Or()) || symbol_Equal(Top, fol_And())) {
+    for (Scan = ArgumentList; !list_Empty(Scan); Scan = list_Cdr(Scan)) 
+      if (symbol_Equal(term_TopSymbol(list_Car(Scan)), fol_Not())) {
+      for (Bscan = ArgumentList; !list_Empty(Bscan); Bscan = list_Cdr(Bscan)) {
+	if (list_Car(Scan) != list_Car(Bscan) &&
+	    fol_AlphaEqual(term_FirstArgument(list_Car(Scan)), list_Car(Bscan))) {
+	  if (symbol_Equal(Top, fol_Or()))
+	    fol_SetTrue(Term);
+	  else
+	    fol_SetFalse(Term);
+	  return TRUE;
+	}
+      }
+    }
+  }
+
+  if (!term_IsAtom(Term))
+    for (Scan = ArgumentList; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+      if (fol_PropagateTautologies(list_Car(Scan)))
+	Hit = TRUE;
+    }
+
+  return Hit;
+}
+
+
+static BOOL fol_AlphaEqualIntern(TERM Term1, TERM Term2, NAT Mark)
+/**************************************************************
+  INPUT:   Two terms which represent formulae and a binding mark.
+  RETURNS: True iff Term2 is equal to Term1 with respect to the
+           renaming of bound variables.
+***************************************************************/
+{
+  LIST    Scan, Bscan;
+  SYMBOL  Top1, Top2;
+
+  Top1  = term_TopSymbol(Term1);
+  Top2  = term_TopSymbol(Term2);
+
+  if (symbol_IsVariable(Top1) && symbol_IsVariable(Top2)) {
+    if (term_VarIsMarked(Top2, Mark))
+      return symbol_Equal(Top1, (SYMBOL)term_BindingValue(Top2));
+    else
+      return symbol_Equal(Top1, Top2);
+  }
+
+  if (!symbol_Equal(Top1, Top2))
+    return FALSE;
+
+  if (fol_IsQuantifier(Top1)) {
+    if (list_Length(fol_QuantifierVariables(Term1)) != list_Length(fol_QuantifierVariables(Term2)))
+      return FALSE;
+    for (Scan = fol_QuantifierVariables(Term1), Bscan = fol_QuantifierVariables(Term2);
+	 !list_Empty(Scan);
+	 Scan = list_Cdr(Scan), Bscan = list_Cdr(Bscan))
+      term_CreateValueBinding(term_TopSymbol(list_Car(Bscan)), Mark, 
+			      (POINTER)term_TopSymbol(list_Car(Scan)));
+
+    if (!fol_AlphaEqualIntern(term_SecondArgument(Term1), term_SecondArgument(Term2), Mark))
+      return FALSE;
+    for (Scan = fol_QuantifierVariables(Term1), Bscan = fol_QuantifierVariables(Term2);
+	 !list_Empty(Scan);
+         Scan = list_Cdr(Scan), Bscan = list_Cdr(Bscan))
+      term_SetBindingMark(term_TopSymbol(list_Car(Bscan)), term_NullMark());
+  }
+  else {
+    if (list_Length(term_ArgumentList(Term1)) != list_Length(term_ArgumentList(Term2)))
+      return FALSE;
+
+    for (Scan = term_ArgumentList(Term1), Bscan = term_ArgumentList(Term2);
+	 !list_Empty(Scan); Scan = list_Cdr(Scan), Bscan = list_Cdr(Bscan))
+      if (!fol_AlphaEqualIntern(list_Car(Scan), list_Car(Bscan), Mark))
+	return FALSE;
+  }
+  return TRUE;
+}
+
+
+BOOL fol_AlphaEqual(TERM Term1, TERM Term2)
+/**************************************************************
+  INPUT:   Two terms of the form Qx(<rest>). All variables that occur in 
+           Term1 and Term2 must be bound by only one quantifier!
+  RETURNS: TRUE iff Term2 is bound renaming of Term1.
+***************************************************************/
+{
+  BOOL Hit;
+
+#ifdef CHECK
+  if (Term1 == term_Null() || Term2 == term_Null()) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In fol_AlphaEqual: Corrupted term as parameter.\n");
+    misc_FinishErrorReport();
+  }
+  if (fol_VarBoundTwice(Term1) || fol_VarBoundTwice(Term2)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In fol_AlphaEqual: Variables are bound more than once.\n");
+    misc_FinishErrorReport();
+  }
+  if (term_InBindingPhase()) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In fol_AlphaEqual: Term context is in binding phase.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  term_StartBinding();
+
+  Hit = fol_AlphaEqualIntern(Term1, Term2, term_ActMark());
+
+  term_StopBinding();
+
+  return Hit;
+}
+
+
+static BOOL fol_VarBoundTwiceIntern(TERM Term, NAT Mark)
+/**************************************************************
+  INPUT:   A term, possibly a NULL Term and a valid binding mark.
+  RETURNS: TRUE iff a variable in <Term> is bound by more than one quantifier.
+***************************************************************/
+{
+  LIST Scan;
+
+  if (Term == term_Null())
+    return FALSE;
+
+  if (term_IsAtom(Term))
+    return FALSE;
+
+  if (!fol_IsQuantifier(term_TopSymbol(Term))) {
+    for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+      if (fol_VarBoundTwiceIntern(list_Car(Scan), Mark))
+	return TRUE;
+  }
+  else {
+    for (Scan = fol_QuantifierVariables(Term); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+      if (!term_VarIsMarked(term_TopSymbol(list_Car(Scan)), Mark))
+	term_SetBindingMark(term_TopSymbol(list_Car(Scan)), Mark);
+      else
+	return TRUE;
+    }
+    if (fol_VarBoundTwiceIntern(term_SecondArgument(Term), Mark))
+      return TRUE;
+    for (Scan = fol_QuantifierVariables(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+      term_SetBindingMark(term_TopSymbol(list_Car(Scan)), term_NullMark());
+  }
+  return FALSE;
+}
+
+
+BOOL fol_VarBoundTwice(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: TRUE iff a variable in term is bound by more than one quantifier.
+***************************************************************/
+{
+  BOOL Hit;
+
+#ifdef CHECK
+  if (term_InBindingPhase()) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n\n Context in fol_VarBoundTwice: term in binding phase\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  term_StartBinding();
+
+  Hit = fol_VarBoundTwiceIntern(Term, (NAT)term_ActMark());
+
+  term_StopBinding();
+
+  return Hit;
+}
+
+
+NAT fol_Depth(TERM Term)
+/**************************************************************
+  INPUT:   A formula.
+  RETURNS: The depth of the formula up to predicate level.
+***************************************************************/
+{
+  NAT  Depth,Help;
+  LIST Scan;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+     misc_StartErrorReport();
+    misc_ErrorReport("\n In fol_Depth: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Depth = 0;
+
+  if (symbol_IsPredicate(term_TopSymbol(Term)))
+    return 1;
+
+  if (fol_IsQuantifier(term_TopSymbol(Term)))
+    return (fol_Depth(term_SecondArgument(Term)) + 1);
+
+  for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+    Help = fol_Depth(list_Car(Scan));
+    if (Help > Depth)
+      Depth = Help;
+  }
+
+  return (Depth+1);
+}
+
+
+static void fol_ApplyContextToTermIntern(CONTEXT Context, TERM Term)
+/********************************************************************
+   INPUT:  A context (Context) and a term (Term).
+   RETURN: void.
+   EFFECT: Term is destructively changed modulo Context.
+*********************************************************************/
+{
+  LIST Scan;
+
+  if (fol_IsQuantifier(term_TopSymbol(Term))) {
+    fol_ApplyContextToTermIntern(Context, term_SecondArgument(Term));
+  }
+  else if (symbol_IsVariable(term_TopSymbol(Term))) {
+    if (cont_VarIsBound(Context, term_TopSymbol(Term)))
+      Term = cont_ApplyBindingsModuloMatching(Context, Term, TRUE);
+  }
+  else {
+    for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan))
+      fol_ApplyContextToTermIntern(Context, list_Car(Scan));
+  }
+}
+
+
+static BOOL fol_CheckApplyContextToTerm(CONTEXT Context, TERM Term)
+/*************************************************************
+   INPUT:   A Context and a term.
+   RETURN:  TRUE iff Context can be applied to Term.
+   COMMENT: Intern funktion of fol_ApplyContextToTerm.
+**************************************************************/
+{
+  LIST Scan;
+  BOOL Apply;
+
+  Apply = TRUE;
+
+  if (fol_IsQuantifier(term_TopSymbol(Term))) {
+    for (Scan=fol_QuantifierVariables(Term); !list_Empty(Scan); Scan=list_Cdr(Scan))
+      if (cont_VarIsBound(Context, term_TopSymbol(list_Car(Scan))))
+	return FALSE;
+    for (Scan=term_ArgumentList(term_SecondArgument(Term)); !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+      if (!fol_CheckApplyContextToTerm(Context, list_Car(Scan)))
+	Apply = FALSE;
+    }
+  }
+  else {
+    for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan))
+      if (!fol_CheckApplyContextToTerm(Context, list_Car(Scan)))
+	Apply = FALSE;
+  }
+  return Apply;
+}
+
+
+BOOL fol_ApplyContextToTerm(CONTEXT Context, TERM Term)
+/***************************************************************
+   INPUT:  A context (Context) and a term (Term).
+   RETURN: TRUE iff context could be applied on Term.
+   EFFECT: Term is destructively changed modulo Context iff possible.
+****************************************************************/
+{
+  if (fol_CheckApplyContextToTerm(Context, Term)) {
+    fol_ApplyContextToTermIntern(Context, Term);
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+
+BOOL fol_SignatureMatchFormula(TERM Formula, TERM Instance, BOOL Variant)
+/********************************************************************
+   INPUT : Two formulas and a flag.
+           It is assumed that the symbol context is clean. 
+   RETURN: TRUE iff <Formula> can be matched to <Instance> by matching
+           variables as well as signature symbols. If <Variant> is TRUE
+	   variables must be matched to variables.
+   EFFECT: The symbol matches are stored in the symbol context.
+*********************************************************************/
+{
+  int     Stack;
+  SYMBOL  FormulaTop, InstanceTop;
+  NAT     ActMark;
+  TERM    ActFormula, ActInstance;
+
+#ifdef CHECK
+  if (!term_IsTerm(Formula) || term_InBindingPhase() || 
+      !term_IsTerm(Instance) || !symbol_ContextIsClean()) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In fol_SignatureMatchFormula: Illegal input or context.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  term_StartBinding();
+
+  Stack       = stack_Bottom();
+  term_NewMark();
+  ActMark     = term_OldMark();
+  ActFormula  = Formula;
+  ActInstance = Instance;
+  
+  do {
+    FormulaTop  = term_TopSymbol(ActFormula);
+    InstanceTop = term_TopSymbol(ActInstance);
+
+    if (!symbol_IsVariable(FormulaTop)) { 
+      if (!symbol_ContextIsBound(FormulaTop)) {
+	if (!symbol_IsJunctor(FormulaTop) && !symbol_IsJunctor(InstanceTop) &&
+	    !fol_IsPredefinedPred(FormulaTop) && !fol_IsPredefinedPred(InstanceTop))
+	  symbol_ContextSetValue(FormulaTop, InstanceTop);    /* Symbols are ALWAYS bound !*/
+	else {
+	  if (!symbol_Equal(FormulaTop, InstanceTop)) {
+	    term_StopBinding();
+	    return FALSE;
+	  }
+	}
+      }
+      else {
+	if (symbol_ContextIsBound(FormulaTop) && 
+	    !symbol_Equal(symbol_ContextGetValue(FormulaTop),InstanceTop)) {
+	  term_StopBinding();
+	  return FALSE;
+	}
+      }
+    }
+
+    if (list_Length(term_ArgumentList(ActFormula)) != list_Length(term_ArgumentList(ActInstance))) {
+      term_StopBinding();
+      return FALSE;	
+    }
+    
+    if (term_IsComplex(ActFormula)) {
+      stack_Push(term_ArgumentList(ActInstance));
+      stack_Push(term_ArgumentList(ActFormula));
+    }
+    else {
+      if (symbol_IsVariable(FormulaTop)) {
+	if (!term_VarIsMarked(FormulaTop, ActMark)) {
+	  if (!Variant || symbol_IsVariable(InstanceTop))
+	    term_CreateValueBinding(FormulaTop, ActMark, (POINTER)InstanceTop);
+	  else {
+	    term_StopBinding();
+	    return FALSE;
+	  }
+	}
+	else {
+	  if (!symbol_Equal((SYMBOL)term_BindingValue(FormulaTop), InstanceTop)) {
+	    term_StopBinding();
+	    return FALSE;
+	  }
+	}
+      }
+    }
+
+    while (!stack_Empty(Stack) && list_Empty(stack_Top())) {
+      stack_Pop();
+      stack_Pop();
+    }
+    if (!stack_Empty(Stack)) {
+      ActFormula  = (TERM)list_Car(stack_Top());
+      ActInstance = (TERM)list_Car(stack_NthTop(1));
+      stack_RplacTop(list_Cdr(stack_Top()));
+      stack_RplacNthTop(1,list_Cdr(stack_NthTop(1)));
+    }
+  } while (!stack_Empty(Stack));
+
+  term_StopBinding();
+
+  return TRUE;
+}
+
+
+BOOL fol_SignatureMatch(TERM Term, TERM Instance, LIST* Bindings, BOOL Variant)
+/*****************************************************************
+   INPUT : Two formulas, a binding list and a boolean flag.
+   RETURN: TRUE iff <Term> can be matched to <Instance> by matching
+           variables as well as signature symbols. If <Variant> is TRUE
+	   variables must be matched to variables. Signature symbol
+	   matchings have to be injective.
+   EFFECT: The symbol matches are stored in the symbol context.
+******************************************************************/
+{
+  int     Stack;
+  SYMBOL  TermTop, InstanceTop;
+  NAT     ActMark;
+  TERM    ActTerm, ActInstance;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term) || !term_IsTerm(Instance)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In fol_SignatureMatch: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Stack       = stack_Bottom();
+  ActMark     = term_OldMark();
+  ActTerm     = Term;
+  ActInstance = Instance;
+  
+  do {
+    TermTop     = term_TopSymbol(ActTerm);
+    InstanceTop = term_TopSymbol(ActInstance);
+
+    if (!symbol_IsVariable(TermTop)) { 
+      if (!symbol_ContextIsBound(TermTop)) {
+	if (!symbol_IsJunctor(TermTop) && !symbol_IsJunctor(InstanceTop) &&
+	    !fol_IsPredefinedPred(TermTop) && !fol_IsPredefinedPred(InstanceTop) &&
+	    !symbol_ContextIsMapped(InstanceTop)) {
+	  symbol_ContextSetValue(TermTop, InstanceTop);    /* Symbols are ALWAYS bound !*/
+	  *Bindings = list_Cons((POINTER)TermTop,*Bindings);
+	}
+	else {
+	  if (!symbol_Equal(TermTop, InstanceTop)) {
+	    return FALSE;
+	  }
+	}
+      }
+      else {
+	if (symbol_ContextIsBound(TermTop) && 
+	    !symbol_Equal(symbol_ContextGetValue(TermTop),InstanceTop)) {
+	  return FALSE;
+	}
+      }
+    }
+
+    if (list_Length(term_ArgumentList(ActTerm)) != list_Length(term_ArgumentList(ActInstance))) {
+      return FALSE;	
+    }
+    
+    if (term_IsComplex(ActTerm)) {
+      stack_Push(term_ArgumentList(ActInstance));
+      stack_Push(term_ArgumentList(ActTerm));
+    }
+    else {
+      if (symbol_IsVariable(TermTop)) {
+	if (!term_VarIsMarked(TermTop, ActMark)) {
+	  if (!Variant || symbol_IsVariable(InstanceTop)) {
+	    term_CreateValueBinding(TermTop, ActMark, (POINTER)InstanceTop);
+	    *Bindings = list_Cons((POINTER)TermTop,*Bindings);
+	  }
+	  else
+	    return FALSE;
+	}
+	else {
+	  if (!symbol_Equal((SYMBOL)term_BindingValue(TermTop), InstanceTop)) {
+	    return FALSE;
+	  }
+	}
+      }
+    }
+
+    while (!stack_Empty(Stack) && list_Empty(stack_Top())) {
+      stack_Pop();
+      stack_Pop();
+    }
+    if (!stack_Empty(Stack)) {
+      ActTerm  = (TERM)list_Car(stack_Top());
+      ActInstance = (TERM)list_Car(stack_NthTop(1));
+      stack_RplacTop(list_Cdr(stack_Top()));
+      stack_RplacNthTop(1,list_Cdr(stack_NthTop(1)));
+    }
+  } while (!stack_Empty(Stack));
+
+  return TRUE;
+}
+
+
+BOOL fol_CheckFormula(TERM Formula)
+/*******************************************************************
+   INPUT : A term Formula.
+   RETURN: TRUE iff  no free variables occure in Formula
+                 and father links are properly set
+		 and argument list lengths match arities
+********************************************************************/
+{
+  LIST FreeVars;
+
+  FreeVars = fol_FreeVariables(Formula);
+
+  if (!list_Empty(FreeVars)) {
+    list_Delete(FreeVars);
+    return FALSE;
+  }
+  
+  return term_CheckTerm(Formula);
+}
diff --git a/test/spass/foldfg.h b/test/spass/foldfg.h
new file mode 100644
index 0000000000000000000000000000000000000000..3704e44e469dd66a7ed59084c04dff0d1901f9be
--- /dev/null
+++ b/test/spass/foldfg.h
@@ -0,0 +1,303 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *              FIRST ORDER LOGIC SYMBOLS                 * */
+/* *                                                        * */
+/* *  $Module:   FOL      DFG                               * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _FOLDFG_
+#define _FOLDFG_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "flags.h"
+#include "unify.h"
+#include "context.h"
+#include "term.h"
+
+/**************************************************************/
+/* Global Variables and Constants (Only seen by macros)       */
+/**************************************************************/
+
+extern SYMBOL  fol_ALL;
+extern SYMBOL  fol_EXIST;
+extern SYMBOL  fol_AND;
+extern SYMBOL  fol_OR;
+extern SYMBOL  fol_NOT;
+extern SYMBOL  fol_IMPLIES;
+extern SYMBOL  fol_IMPLIED;
+extern SYMBOL  fol_EQUIV;
+extern SYMBOL  fol_VARLIST;
+extern SYMBOL  fol_EQUALITY;
+extern SYMBOL  fol_TRUE;
+extern SYMBOL  fol_FALSE;
+
+/**************************************************************/
+/* Access to the first-order symbols.                         */
+/**************************************************************/
+
+static __inline__ SYMBOL fol_All(void)
+{
+  return fol_ALL;
+}
+
+static __inline__ SYMBOL fol_Exist(void)
+{
+  return fol_EXIST;
+}
+
+static __inline__ SYMBOL fol_And(void)
+{
+  return fol_AND;
+}
+
+static __inline__ SYMBOL fol_Or(void)
+{
+  return fol_OR;
+}
+
+static __inline__ SYMBOL fol_Not(void)
+{
+  return fol_NOT;
+}
+
+static __inline__ SYMBOL fol_Implies(void)
+{
+  return fol_IMPLIES;
+}
+
+static __inline__ SYMBOL fol_Implied(void)
+{
+  return fol_IMPLIED;
+}
+
+static __inline__ SYMBOL fol_Equiv(void)
+{
+  return fol_EQUIV;
+}
+
+static __inline__ SYMBOL fol_Varlist(void)
+{
+  return fol_VARLIST;
+}
+
+static __inline__ SYMBOL fol_Equality(void)
+{
+  return fol_EQUALITY;
+}
+
+static __inline__ SYMBOL fol_True(void)
+{
+  return fol_TRUE;
+}
+
+static __inline__ SYMBOL fol_False(void)
+{
+  return fol_FALSE;
+}
+
+/**************************************************************/
+/* Macros                                                     */
+/**************************************************************/
+
+static __inline__ BOOL fol_IsQuantifier(SYMBOL S)
+{
+  return symbol_Equal(fol_ALL,S) || symbol_Equal(fol_EXIST,S);
+}
+
+static __inline__ BOOL fol_IsTrue(TERM S)
+{
+  return symbol_Equal(fol_TRUE,term_TopSymbol(S));
+}
+
+static __inline__ BOOL fol_IsFalse(TERM S)
+{
+  return symbol_Equal(fol_FALSE,term_TopSymbol(S));
+}
+
+static  __inline__ LIST fol_QuantifierVariables(TERM T)
+  /* T's top symbol must be a quantifier ! */
+{
+  return term_ArgumentList(term_FirstArgument(T));
+}
+
+static __inline__ BOOL fol_IsLiteral(TERM T)
+{
+  return symbol_IsPredicate(term_TopSymbol(T)) ||
+    (symbol_Equal(term_TopSymbol(T),fol_Not()) && 
+     symbol_IsPredicate(term_TopSymbol(term_FirstArgument(T))));
+}
+
+static __inline__ BOOL fol_IsNegativeLiteral(TERM T)
+{
+  return (symbol_Equal(term_TopSymbol(T),fol_Not()) && 
+	  symbol_IsPredicate(term_TopSymbol(term_FirstArgument(T))));
+}
+
+
+static __inline__ BOOL fol_IsJunctor(SYMBOL S)
+{
+  return fol_IsQuantifier(S) || symbol_Equal(S, fol_AND) || 
+    symbol_Equal(S, fol_OR) || symbol_Equal(S, fol_NOT) ||
+    symbol_Equal(S, fol_IMPLIED) ||  symbol_Equal(S, fol_VARLIST) ||
+    symbol_Equal(S, fol_IMPLIES) || symbol_Equal(S, fol_EQUIV);
+}
+
+static __inline__ BOOL fol_IsPredefinedPred(SYMBOL S)
+{
+  return symbol_Equal(S, fol_EQUALITY) || symbol_Equal(S, fol_TRUE) ||
+    symbol_Equal(S, fol_FALSE);
+}
+
+static __inline__ TERM fol_Atom(TERM Lit)
+{
+  if (term_TopSymbol(Lit) == fol_NOT)
+    return term_FirstArgument(Lit);
+  else
+    return Lit;
+}
+
+static __inline__ BOOL fol_IsEquality(TERM Term)
+{
+  return term_TopSymbol(Term) == fol_EQUALITY;
+}
+
+
+static __inline__ BOOL fol_IsAssignment(TERM Term)
+{
+  return (term_TopSymbol(Term) == fol_EQUALITY &&
+	  ((term_IsVariable(term_FirstArgument(Term)) &&
+	    !term_ContainsVariable(term_SecondArgument(Term),
+				   term_TopSymbol(term_FirstArgument(Term)))) ||
+	   (term_IsVariable(term_SecondArgument(Term)) &&
+	    !term_ContainsVariable(term_FirstArgument(Term),
+				   term_TopSymbol(term_SecondArgument(Term))))));
+}
+
+
+static __inline__ LIST fol_DeleteFalseTermFromList(LIST List)
+/**************************************************************
+  INPUT:   A list of terms.
+  RETURNS: The list where all terms equal to the 'False' term are removed.
+  EFFECTS:  'False' is a special predicate from the fol module.
+           Terms are compared with respect to the term_Equal function.
+           The terms are deleted, too.
+***************************************************************/
+{
+  return list_DeleteElementIfFree(List, (BOOL (*)(POINTER))fol_IsFalse,
+				  (void (*)(POINTER))term_Delete);
+}
+
+
+static __inline__ LIST fol_DeleteTrueTermFromList(LIST List)
+/**************************************************************
+  INPUT:   A list of terms.
+  RETURNS: The list where all terms equal to the 'True' term are removed.
+  EFFECTS:  'True' is a special predicate from the fol module.
+           Terms are compared with respect to the term_Equal function.
+           The terms are deleted, too.
+***************************************************************/
+{
+  return list_DeleteElementIfFree(List, (BOOL (*)(POINTER))fol_IsTrue,
+				  (void (*)(POINTER))term_Delete);
+}
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+void   fol_Init(BOOL, PRECEDENCE);
+SYMBOL fol_IsStringPredefined(const char*);
+TERM   fol_CreateQuantifier(SYMBOL, LIST, LIST);
+TERM   fol_CreateQuantifierAddFather(SYMBOL, LIST, LIST);
+LIST   fol_GetNonFOLPredicates(void);
+TERM   fol_ComplementaryTerm(TERM);
+LIST   fol_GetAssignments(TERM);
+void   fol_Free(void);
+void   fol_CheckFatherLinks(TERM);
+BOOL   fol_FormulaIsClause(TERM);
+void   fol_FPrintOtterOptions(FILE*, BOOL, FLAG_TDFG2OTTEROPTIONSTYPE);
+void   fol_FPrintOtter(FILE*, LIST, FLAG_TDFG2OTTEROPTIONSTYPE);
+void   fol_FPrintDFGSignature(FILE*);
+void   fol_PrettyPrintDFG(TERM);
+void   fol_PrintDFG(TERM);
+void   fol_FPrintDFG(FILE*, TERM);
+void   fol_FPrintDFGProblem(FILE*, const char*, const char*, const char*, const char*, LIST, LIST);
+void   fol_PrintPrecedence(PRECEDENCE);
+void   fol_FPrintPrecedence(FILE*, PRECEDENCE);
+LIST   fol_Instances(TERM, TERM);
+LIST   fol_Generalizations(TERM, TERM);
+TERM   fol_MostGeneralFormula(LIST);
+void   fol_NormalizeVars(TERM);
+void   fol_NormalizeVarsStartingAt(TERM, SYMBOL);
+LIST   fol_FreeVariables(TERM);
+LIST   fol_BoundVariables(TERM);
+BOOL   fol_VarOccursFreely(TERM,TERM);
+BOOL   fol_AssocEquation(TERM, SYMBOL *);
+BOOL   fol_DistributiveEquation(TERM, SYMBOL*, SYMBOL*);
+void   fol_ReplaceVariable(TERM, SYMBOL, TERM);
+void   fol_PrettyPrint(TERM);
+LIST   fol_GetSubstEquations(TERM);
+TERM   fol_GetBindingQuantifier(TERM, SYMBOL);
+int    fol_TermPolarity(TERM, TERM);
+BOOL   fol_PolarCheck(TERM, TERM);
+void   fol_PopQuantifier(TERM);
+void   fol_DeleteQuantifierVariable(TERM,SYMBOL);
+void   fol_SetTrue(TERM);
+void   fol_SetFalse(TERM);
+void   fol_RemoveImplied(TERM);
+BOOL   fol_PropagateFreeness(TERM);
+BOOL   fol_PropagateWitness(TERM);
+BOOL   fol_PropagateTautologies(TERM);
+BOOL   fol_AlphaEqual(TERM, TERM);
+BOOL   fol_VarBoundTwice(TERM);
+NAT    fol_Depth(TERM);
+BOOL   fol_ApplyContextToTerm(CONTEXT, TERM);
+BOOL   fol_CheckFormula(TERM);
+BOOL   fol_SignatureMatchFormula(TERM, TERM, BOOL);
+BOOL   fol_SignatureMatch(TERM, TERM, LIST*, BOOL);
+
+#endif
diff --git a/test/spass/graph.c b/test/spass/graph.c
new file mode 100644
index 0000000000000000000000000000000000000000..732fa0e82f6a5a275b6e293544d1b2a266944777
--- /dev/null
+++ b/test/spass/graph.c
@@ -0,0 +1,318 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                       GRAPHS                           * */
+/* *                                                        * */
+/* *  $Module:   GRAPH                                      * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1998, 2000, 2001 MPI fuer Informatik    * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "graph.h"
+
+
+static LIST graph_ROOTS;      /* used as stack by SCC algorithm */
+static LIST graph_UNFINISHED; /* used as stack by SCC algorithm */
+
+
+void graph_NodePrint(GRAPHNODE Node)
+/**************************************************************
+  INPUT:   A graph node.
+  RETURNS: Nothing.
+  EFFECT:  Prints some node information to stdout.
+***************************************************************/
+{
+  printf("(%d,%d,%d) ", graph_NodeNumber(Node), graph_NodeDfsNum(Node),
+	 graph_NodeCompNum(Node));
+}
+
+
+GRAPH graph_Create(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: A new graph without nodes and edges.
+***************************************************************/
+{
+  GRAPH result;
+
+  result = memory_Malloc(sizeof(GRAPH_STRUCT));
+  result->size      = 0;
+  result->dfscount  = 0;
+  result->compcount = 0;
+  result->nodes     = list_Nil();
+  return result;
+}
+
+
+void graph_Delete(GRAPH Graph)
+/**************************************************************
+  INPUT:   A graph.
+  RETURNS: Nothing.
+  EFFECT:  All memory required by the graph and its nodes
+           is freed.
+***************************************************************/
+{
+  for ( ; !list_Empty(Graph->nodes); Graph->nodes = list_Pop(Graph->nodes)) {
+    list_Delete(graph_NodeNeighbors(list_Car(Graph->nodes)));
+    memory_Free(list_Car(Graph->nodes), sizeof(GRAPHNODE_STRUCT));
+  }
+  memory_Free(Graph, sizeof(GRAPH_STRUCT));
+}
+
+
+GRAPHNODE graph_GetNode(GRAPH Graph, NAT Number)
+/**************************************************************
+  INPUT:   A graph and the ID of a node.
+  RETURNS: The node with the requested number or NULL
+           if such a node doesn't exist.
+***************************************************************/
+{
+  LIST scan;
+
+  for (scan = Graph->nodes; !list_Empty(scan); scan= list_Cdr(scan)) {
+    if (graph_NodeNumber(list_Car(scan)) == Number)
+      return list_Car(scan);
+  }
+
+  return NULL;
+}
+
+
+GRAPHNODE graph_AddNode(GRAPH Graph, NAT Number)
+/**************************************************************
+  INPUT:   A graph and the ID of a node.
+  RETURNS: A node with the requested number.
+  EFFECT:  If the graph has no such node, a new node is created.
+***************************************************************/
+{
+  GRAPHNODE result;
+
+  result = graph_GetNode(Graph, Number);
+  if (result == NULL) {
+    result = memory_Malloc(sizeof(GRAPHNODE_STRUCT));
+    Graph->nodes      = list_Cons(result, Graph->nodes);
+    result->number    = Number;
+    result->dfs_num   = -1;
+    result->comp_num  = -1;
+    result->info      = NULL;
+    result->neighbors = list_Nil();
+  }
+  return result;
+}
+
+
+void graph_AddEdge(GRAPHNODE From, GRAPHNODE To)
+/**************************************************************
+  INPUT:   Two graph nodes.
+  RETURNS: Nothing.
+  EFFECT:  Adds a single (directed) edge (From, To).
+***************************************************************/
+{
+  From->neighbors = list_Cons(To, From->neighbors);
+}
+
+
+void graph_DeleteEdge(GRAPHNODE From, GRAPHNODE To)
+/**************************************************************
+  INPUT:   Two graph nodes.
+  RETURNS: Nothing.
+  EFFECT:  Removes ALL edges (From, To) from a graph.
+***************************************************************/
+{
+  From->neighbors = list_PointerDeleteElement(From->neighbors, To);
+}
+
+
+void graph_DeleteDuplicateEdges(GRAPH Graph)
+/**************************************************************
+  INPUT:   A graph.
+  RETURNS: Nothing.
+  EFFECT:  Removes duplicate edges between all nodes.
+***************************************************************/
+{
+  LIST scan;
+
+  for (scan = graph_Nodes(Graph); !list_Empty(scan); scan = list_Cdr(scan)) {
+    GRAPHNODE n = list_Car(scan);
+    n->neighbors = list_PointerDeleteDuplicates(n->neighbors);
+  }
+}
+
+
+void graph_SortNodes(GRAPH Graph, BOOL (*SortFunction)(GRAPHNODE, GRAPHNODE))
+/**************************************************************
+  INPUT:   A graph and a sorting function for graph nodes.
+  RETURNS: Nothing.
+  EFFECT:  The node list is sorted with respect to the
+           sorting function.
+***************************************************************/
+{
+  Graph->nodes = list_Sort(graph_Nodes(Graph),
+			   (BOOL (*) (POINTER, POINTER)) SortFunction);  
+}
+
+
+static void graph_ReinitDFS(GRAPH Graph)
+/**************************************************************
+  INPUT:   A graph.
+  RETURNS: Nothing.
+  EFFECT:  Prepares the graph and its nodes for a new DFS run.
+           The DFS and COMP numbers are reset.
+***************************************************************/
+{
+  LIST scan;
+
+  Graph->dfscount  = 0;
+  Graph->compcount = 0;
+
+  for (scan = graph_Nodes(Graph); !list_Empty(scan); scan = list_Cdr(scan)) {
+    graph_NodeSetDfsNum(list_Car(scan), -1);
+    graph_NodeSetCompNum(list_Car(scan), -1);
+  }
+}
+
+
+static void graph_InternSCC(GRAPH Graph, GRAPHNODE Node)
+/**************************************************************
+  INPUT:   A graph and a node of the graph.
+  RETURNS: Nothing.
+  EFFECT:  This is an internal function used by
+           graph_StronglyConnnectedComponents.
+	   It sets information in the graph structure which
+           specifies the strongly connected components of
+           the graph.
+***************************************************************/
+{
+  GRAPHNODE n;
+  LIST      scan;
+  NAT       act_dfs;
+
+  act_dfs = (Graph->dfscount)++;
+  graph_NodeSetDfsNum(Node, act_dfs);
+
+  graph_UNFINISHED = list_Push(Node, graph_UNFINISHED);
+  graph_ROOTS      = list_Push(Node, graph_ROOTS);
+
+  /* putchar('\n'); list_Apply(graph_NodePrint, graph_UNFINISHED);
+     putchar('\n'); list_Apply(graph_NodePrint, graph_ROOTS);
+     fflush(stdout); DBG */
+
+  for (scan = graph_NodeNeighbors(Node);
+       !list_Empty(scan); scan = list_Cdr(scan)) {
+    n = list_Car(scan);
+    if (!graph_NodeVisited(n)) {
+      graph_InternSCC(Graph, n);  /* Visit <n> */
+    } else if (!graph_NodeCompleted(n)) {
+      /* <n> was visited but is not yet in a permanent component */
+      NAT dfs_num_of_n = graph_NodeDfsNum(n);
+      while (!list_StackEmpty(graph_ROOTS) &&
+	     graph_NodeDfsNum(list_Top(graph_ROOTS)) > dfs_num_of_n)
+	graph_ROOTS = list_Pop(graph_ROOTS);
+      /* putchar('\n'); list_Apply(symbol_Print, graph_UNFINISHED);
+	 putchar('\n'); list_Apply(symbol_Print, graph_ROOTS);
+	 fflush(stdout); DBG */
+    }
+  }
+
+  /* printf("\nDFS(%u) complete.", graph_NodeNumber(Node)); DBG */
+
+  if (Node == list_Top(graph_ROOTS)) {
+    /* Node is root of a component, so make this component permanent */
+    while (!list_StackEmpty(graph_UNFINISHED) &&
+	   graph_NodeDfsNum(list_Top(graph_UNFINISHED)) >= act_dfs) {
+      n = list_Top(graph_UNFINISHED);
+      graph_UNFINISHED = list_Pop(graph_UNFINISHED);
+      graph_NodeSetCompNum(n, Graph->compcount);
+    }
+    Graph->compcount++;
+    graph_ROOTS = list_Pop(graph_ROOTS);
+  }
+
+  /* putchar('\n'); list_Apply(graph_NodePrint, graph_UNFINISHED);
+     putchar('\n'); list_Apply(graph_NodePrint, graph_ROOTS); fflush(stdout); DBG */
+}
+
+
+NAT graph_StronglyConnectedComponents(GRAPH Graph)
+/**************************************************************
+  INPUT:   A graph.
+  RETURNS: The number of strongly connected components
+           in the graph.
+  EFFECT:  This function sets the component numbers of all nodes.
+           Two nodes that belong to the same component will have
+           the same component number.
+	   The algorithm is taken from the script
+           "Datenstrukturen und Algorithmen" by Kurt Mehlhorn
+           in winter semester 1997/98, pages 86-92.
+***************************************************************/
+{
+  LIST scan;
+
+  if (Graph->dfscount != 0)
+    graph_ReinitDFS(Graph); /* Reinitializations for Depth First Search */
+
+  graph_ROOTS          = list_Nil();
+  graph_UNFINISHED     = list_Nil();
+
+  for (scan = graph_Nodes(Graph); !list_Empty(scan); scan = list_Cdr(scan)) {
+    if (!graph_NodeVisited(list_Car(scan)))
+      graph_InternSCC(Graph, list_Car(scan));
+  }
+  return Graph->compcount;
+}
+
+
+void graph_Print(GRAPH Graph)
+/**************************************************************
+  INPUT:   A graph.
+  RETURNS: Nothing.
+  EFFECT:  The adjacency list representation of the graph
+           is printed to stdout.
+***************************************************************/
+{
+  LIST scan1, scan2;
+  
+  for (scan1 = graph_Nodes(Graph); !list_Empty(scan1); scan1 = list_Cdr(scan1)) {
+    printf("\n%u -> ", graph_NodeNumber(list_Car(scan1)));
+    for (scan2 = graph_NodeNeighbors(list_Car(scan1)); !list_Empty(scan2);
+	 scan2 = list_Cdr(scan2)) {
+      printf("%u,", graph_NodeNumber(list_Car(scan2)));
+    }
+  }
+}
diff --git a/test/spass/graph.h b/test/spass/graph.h
new file mode 100644
index 0000000000000000000000000000000000000000..411f4f26a51222e049df4eab91ae060408b4f281
--- /dev/null
+++ b/test/spass/graph.h
@@ -0,0 +1,148 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                       GRAPHS                           * */
+/* *                                                        * */
+/* *  $Module:   GRAPH                                      * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1998, 2001 MPI fuer Informatik          * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _GRAPH_
+#define _GRAPH_
+
+#include "list.h"
+
+typedef struct {
+  NAT     number;
+  int     dfs_num;
+  int     comp_num;  /* completion number */
+  POINTER info;      /* user defined information */
+  LIST    neighbors;
+} GRAPHNODE_STRUCT, *GRAPHNODE;
+
+typedef struct {
+  NAT  size;       /* number of nodes */
+  LIST nodes;      /* list of GRAPHNODES */
+  NAT  dfscount;   /* used for DFS */
+  NAT  compcount;  /* used for DFS */
+} GRAPH_STRUCT, *GRAPH;
+
+static __inline__ NAT graph_NodeNumber(GRAPHNODE Node)
+{
+  return Node->number;
+}
+
+static __inline__ int graph_NodeDfsNum(GRAPHNODE Node)
+{
+  return Node->dfs_num;
+}
+
+static __inline__ void graph_NodeSetDfsNum(GRAPHNODE Node, int Number)
+{
+  Node->dfs_num = Number;
+}
+
+static __inline__ int graph_NodeCompNum(GRAPHNODE Node)
+{
+  return Node->comp_num;
+}
+
+static __inline__ void graph_NodeSetCompNum(GRAPHNODE Node, int Number)
+{
+  Node->comp_num = Number;
+}
+
+static __inline__ LIST graph_NodeNeighbors(GRAPHNODE Node)
+{
+  return Node->neighbors;
+}
+
+static __inline__ POINTER graph_NodeInfo(GRAPHNODE Node)
+{
+  return Node->info;
+}
+
+static __inline__ void graph_NodeSetInfo(GRAPHNODE Node, POINTER Info)
+{
+  Node->info = Info;
+}
+
+static __inline__ NAT graph_NodeOutdegree(GRAPHNODE Node)
+{
+  return list_Length(graph_NodeNeighbors(Node));
+}
+
+static __inline__ BOOL graph_NodeVisited(GRAPHNODE Node)
+{
+  return graph_NodeDfsNum(Node) >= 0;
+}
+
+static __inline__ BOOL graph_NodeCompleted(GRAPHNODE Node)
+{
+  return graph_NodeCompNum(Node) >= 0;
+}
+
+static __inline__ NAT graph_Size(GRAPH Graph)
+{
+  return Graph->size;
+}
+
+static __inline__ LIST graph_Nodes(GRAPH Graph)
+{
+  return Graph->nodes;
+}
+
+GRAPH     graph_Create(void);
+void      graph_Delete(GRAPH);
+
+GRAPHNODE graph_GetNode(GRAPH, NAT);
+GRAPHNODE graph_AddNode(GRAPH, NAT);
+
+void      graph_AddEdge(GRAPHNODE, GRAPHNODE);
+void      graph_DeleteEdge(GRAPHNODE, GRAPHNODE);
+void      graph_DeleteDuplicateEdges(GRAPH);
+
+void      graph_SortNodes(GRAPH, BOOL (*)(GRAPHNODE, GRAPHNODE));
+NAT       graph_StronglyConnectedComponents(GRAPH);
+
+void      graph_NodePrint(GRAPHNODE Node);
+void      graph_Print(GRAPH);
+
+#endif
diff --git a/test/spass/hash.c b/test/spass/hash.c
new file mode 100644
index 0000000000000000000000000000000000000000..d9f996c06be7517f30ea6e70d23a94435811fc60
--- /dev/null
+++ b/test/spass/hash.c
@@ -0,0 +1,115 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                 SIMPLE HASHING                         * */
+/* *                                                        * */
+/* *  $Module:   HASH                                       * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1999, 2000, 2001                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "hash.h"
+
+/**************************************************************/
+/* Global Variables                                           */
+/**************************************************************/
+
+LIST hash_TABLE[hash__SIZE];
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+void hash_Init(void)
+{
+  int i;
+  
+  for (i = 0; i < hash__SIZE; i++)
+    hash_PutList(i, list_Nil());
+}
+
+void hash_Reset(void)
+{
+  int  i;
+  LIST Scan;
+  
+  for (i = 0; i < hash__SIZE; i++) {
+    Scan = hash_List(i);
+    while (!list_Empty(Scan)) {
+      list_Free(list_Car(Scan));
+      Scan = list_Cdr(Scan);
+    }
+    list_Delete(hash_List(i));
+    hash_PutList(i, list_Nil());
+  }
+}
+
+void hash_ResetWithValue(void (*ValueDelete)(POINTER))
+{
+  int  i;
+  LIST Scan;
+  
+  for (i = 0; i < hash__SIZE; i++) {
+    Scan = hash_List(i);
+    while (!list_Empty(Scan)) {
+      ValueDelete(list_PairSecond(list_Car(Scan)));
+      list_Free(list_Car(Scan));
+      Scan = list_Cdr(Scan);
+    }
+    list_Delete(hash_List(i));
+    hash_PutList(i, list_Nil());
+  }
+}
+
+POINTER hash_Get(POINTER key)
+{
+  LIST Scan;
+
+  Scan = hash_List(hash_Index(key));
+  
+  while (!list_Empty(Scan)) {
+    if (list_PairFirst(list_Car(Scan)) == key)
+      return list_PairSecond(list_Car(Scan));
+    Scan = list_Cdr(Scan);
+  }
+
+  return NULL;
+}
diff --git a/test/spass/hash.h b/test/spass/hash.h
new file mode 100644
index 0000000000000000000000000000000000000000..3556e5dcc005e65210edd85f41f903a5207dfa96
--- /dev/null
+++ b/test/spass/hash.h
@@ -0,0 +1,107 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                 SIMPLE HASHING                         * */
+/* *                                                        * */
+/* *  $Module:   HASH                                       * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1999, 2000, 2001                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _HASH_
+#define _HASH_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "list.h"
+
+
+/**************************************************************/
+/* Structures                                                 */
+/**************************************************************/
+
+#define hash__SIZE 29            /* a prime */
+
+/* Each Entry is a list of pairs <key,value> */
+extern LIST hash_TABLE[hash__SIZE];
+
+
+/**************************************************************/
+/* Inline Functions                                           */
+/**************************************************************/
+
+static __inline__ NAT hash_Index(POINTER Key)
+{
+  return (NAT)Key % hash__SIZE;
+}
+
+static __inline__ LIST hash_List(NAT Index)
+{
+  return hash_TABLE[Index];
+}
+
+static __inline__ void hash_PutList(NAT Index, LIST List)
+{
+  hash_TABLE[Index] = List;
+}
+
+static __inline__ void hash_Put(POINTER Key, POINTER Value)
+{
+  hash_PutList(hash_Index(Key), list_Cons(list_PairCreate((POINTER)Key, Value),
+					  hash_List(hash_Index(Key))));
+}
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+void    hash_Init(void);
+void    hash_Reset(void);
+void    hash_ResetWithValue(void (*)(POINTER));
+
+POINTER hash_Get(POINTER);
+
+
+#endif
+
+
diff --git a/test/spass/hasharray.c b/test/spass/hasharray.c
new file mode 100644
index 0000000000000000000000000000000000000000..9822b71c1075394286a97a9fa27ecf6baac73989
--- /dev/null
+++ b/test/spass/hasharray.c
@@ -0,0 +1,138 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                       HASHING                          * */
+/* *                                                        * */
+/* *  $Module:   HASHARRAY                                  * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1997, 1998, 2000, 2001                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "hasharray.h"
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+HASH hsh_Create(void)
+/**************************************************************
+  RETURNS: A new, empty hasharray
+***************************************************************/
+{
+  HASH h;
+  NAT  l;
+  h = (LIST*) memory_Malloc(sizeof(LIST) * hsh__SIZE);
+  for (l=0; l < hsh__SIZE; l++)
+    h[l] = list_Nil();
+  return h;
+}
+
+void hsh_Reset(HASH H)
+/**************************************************************
+  INPUT:   A hasharray
+  EFFECT:  Deletes all information stored in the array but keeps
+           the array itself.
+           Keys and data items are not deleted !
+***************************************************************/
+{
+  int  i;
+  LIST Scan, Pair;
+  for (i = 0; i < hsh__SIZE; i++) {
+    for (Scan = H[i]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+      Pair = list_Car(Scan);
+      list_Delete(list_PairSecond(Pair));
+      list_PairFree(Pair);
+    }
+    list_Delete(H[i]);
+    H[i] = list_Nil();
+  }
+}
+
+void hsh_Delete(HASH H)
+/**************************************************************
+  INPUT:   A hasharray
+  EFFECT:  Deletes all information stored in the array and 
+           the array itself.
+           Keys and data items are not deleted !
+***************************************************************/            
+{
+  hsh_Reset(H);
+  memory_Free(H, sizeof(LIST) * hsh__SIZE);
+}
+
+LIST hsh_GetAllEntries(HASH H)
+/**************************************************************
+  INPUT:   A hasharray
+  RETURNS: A new list of all data items stored in the hasharray
+***************************************************************/
+{
+  LIST Scan, Result;
+  NAT i;
+  Result = list_Nil();
+  for (i = 0; i < hsh__SIZE; i++) {
+    for (Scan = H[i]; !list_Empty(Scan); Scan = list_Cdr(Scan))
+      Result = list_Nconc(Result, list_Copy(list_PairSecond(list_Car(Scan))));
+  }
+  return Result;
+}
+
+void hsh_Check(HASH H)
+/**************************************************************
+  INPUT:   A hasharray
+  EFFECT:  Traverses the whole array and the lists to find dangling pointers.
+***************************************************************/
+{
+  LIST          Scan, Scan2, Pair;
+  NAT           i;
+  unsigned long Key;
+  for (i = 0; i < hsh__SIZE; i++) {
+    for (Scan = H[i]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+      Pair = list_Car(Scan);
+      Key = (unsigned long)list_PairFirst(Pair);
+      for (Scan2 = list_PairSecond(Pair); !list_Empty(Scan2); Scan2 = list_Cdr(Scan2)) {
+	POINTER Value;
+	char Z;
+	Value = list_Car(Scan2);
+	Z = * ((char*) Value);
+      }
+    }
+  }
+}
diff --git a/test/spass/hasharray.h b/test/spass/hasharray.h
new file mode 100644
index 0000000000000000000000000000000000000000..de6e118af2e8411ce08024ffc43262429beef3ec
--- /dev/null
+++ b/test/spass/hasharray.h
@@ -0,0 +1,246 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                       HASHING                          * */
+/* *                                                        * */
+/* *  $Module:   HASHARRAY                                  * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1997, 1998, 1999, 2000, 2001            * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _HASHARRAY_
+#define _HASHARRAY_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "list.h"
+
+/**************************************************************/
+/* Structures                                                 */
+/**************************************************************/
+
+#define hsh__SIZE 29            /* a prime */
+
+/* Each Entry is a list of pairs <key,list of values> */
+
+typedef LIST* HASH;
+
+void hsh_Check(HASH H);
+
+/**************************************************************/
+/* Inline Functions                                           */
+/**************************************************************/
+
+static __inline__ unsigned long hsh_Index(POINTER Key)
+/**************************************************************
+  INPUT:   A pointer
+  RETURNS: A key for the hasharray
+***************************************************************/
+{
+  return (unsigned long)Key % hsh__SIZE;
+}
+
+static __inline__ void hsh_Put(HASH H, POINTER Key, POINTER Value)
+/**************************************************************
+  INPUT:   A hasharray, a pointer used as key and a pointer to a data item
+  EFFECT:  Add Value to the list of data items associated with the key,
+           if it isn't a member already
+***************************************************************/
+{
+  LIST Scan, Pair;
+  unsigned long HashKey;
+  HashKey = hsh_Index(Key);
+  for (Scan = H[HashKey]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    Pair = list_Car(Scan);
+    if (list_PairFirst(Pair) == Key) {
+      if (!list_PointerMember(list_PairSecond(Pair), Value))
+	list_Rplacd(Pair, list_Cons(Value, list_PairSecond(Pair)));
+#ifdef CHECK
+      hsh_Check(H);
+#endif
+      return;
+    }
+  }
+  H[HashKey] = list_Cons(list_PairCreate(Key, list_List(Value)), H[HashKey]);
+#ifdef CHECK
+  hsh_Check(H);
+#endif
+}
+
+static __inline__ void hsh_PutList(HASH H, POINTER Key, LIST List)
+/**************************************************************
+  INPUT:   A hasharray, a pointer used as key and a list of data items
+  EFFECT:  Add the list to the list of data items associated with the key,
+           and delete all duplicates.
+***************************************************************/
+{
+  LIST Scan, Pair;
+  unsigned long HashKey;
+
+  HashKey = hsh_Index(Key);
+  for (Scan = H[HashKey]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    Pair = list_Car(Scan);
+    if (list_PairFirst(Pair) == Key) {
+      list_Rplacd(Pair, list_Nconc(list_PairSecond(Pair), List));
+#ifdef CHECK
+      hsh_Check(H);
+#endif
+      return;
+    }
+  }
+  H[HashKey] = list_Cons(list_PairCreate(Key, List), H[HashKey]);
+#ifdef CHECK
+  hsh_Check(H);
+#endif
+}
+
+static __inline__ void hsh_PutListWithCompareFunc(HASH H, POINTER Key, 
+						  LIST List,
+						  BOOL (*Test)(POINTER, POINTER), 
+						  unsigned long (*HashFunc)(POINTER))
+/**************************************************************
+  INPUT:   A hasharray, a pointer used as key, a list of data
+           items, a test function for key equality and a
+	   hashing function.
+  EFFECT:  Add the list to the list of data items associated
+           with the key, and delete all duplicates.
+***************************************************************/
+{
+  LIST Scan, Pair;
+  unsigned long HashKey;
+
+  HashKey = (unsigned long) HashFunc(Key);
+  for (Scan = H[HashKey]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    Pair = (LIST) list_Car(Scan);
+    if (Test(list_PairFirst(Pair), Key)) {
+      list_Rplacd(Pair, list_Nconc(list_PairSecond(Pair), List));
+#ifdef CHECK
+      hsh_Check(H);
+#endif
+      return;
+    }
+  }
+  H[HashKey] = list_Cons(list_PairCreate(Key, List), H[HashKey]);
+#ifdef CHECK
+  hsh_Check(H);
+#endif
+}
+
+static __inline__ LIST hsh_Get(HASH H, POINTER Key)
+/**************************************************************
+  INPUT:   A hasharray and a pointer used as key
+  RETURNS: The list of data items associated with the key
+***************************************************************/
+{
+  LIST Scan, Pair;
+
+  for (Scan = H[hsh_Index(Key)]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    Pair = list_Car(Scan);
+    if (list_PairFirst(Pair) == Key)
+      return list_PairSecond(Pair);
+  }
+  return NULL;
+}
+
+static __inline__ void hsh_DelItem(HASH H, POINTER Key)
+/**************************************************************
+  INPUT:   A hasharray and a pointer used as key
+  RETURNS: The information associated with the key is deleted
+***************************************************************/
+{
+  LIST Scan, Pair;
+  unsigned long k;
+
+  k = hsh_Index(Key);
+  for (Scan = H[k]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    Pair = list_Car(Scan);
+    if (list_PairFirst(Pair) == Key) {
+      list_Delete(list_PairSecond(Pair));
+      list_PairFree(Pair);
+      H[k] = list_PointerDeleteElement(H[k], Pair);
+      return;
+    }
+  }
+}
+
+static __inline__ LIST hsh_GetWithCompareFunc(HASH H, POINTER Key,
+					      BOOL (*Test)(POINTER, POINTER),
+					      unsigned long (*HashFunc)(POINTER))
+/**************************************************************
+  INPUT:   A hasharray, a pointer used as key, a compare function
+           for keys and a hash function for keys.
+  RETURNS: The list of data items associated with the key
+***************************************************************/
+{
+  LIST Scan, Pair;
+
+  for (Scan = H[HashFunc(Key)]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    Pair = list_Car(Scan);
+    if (Test(list_PairFirst(Pair), Key))
+      return list_PairSecond(Pair);
+  }
+  return NULL;
+}
+
+
+static __inline__ unsigned long hsh_StringHashKey(const char* Label)
+{
+  unsigned long i, s;
+  s = 0;
+  for (i = 0; i <= strlen(Label); i++)
+    s += Label[i];
+  s = s % hsh__SIZE;
+  return s;
+}
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+HASH hsh_Create(void);
+void hsh_Reset(HASH H);
+void hsh_Delete(HASH H);
+LIST hsh_GetAllEntries(HASH H);
+
+#endif
+
+
diff --git a/test/spass/ia.h b/test/spass/ia.h
new file mode 100644
index 0000000000000000000000000000000000000000..4cf2fb9cbeeb3e60d41558bcba96c4bf31e2e2e1
--- /dev/null
+++ b/test/spass/ia.h
@@ -0,0 +1,58 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *       INTERFACE FOR SPASS INTERACTICE MODE             * */
+/* *                                                        * */
+/* *  $Module:   DFG                                        * */
+/* *                                                        * */
+/* *  Copyright (C) 1997, 1999, 2000, 2001                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _IA_
+#define _IA_
+
+#include <stdio.h>
+#include "list.h"
+#include "flags.h"
+
+/* Parser functions */
+LIST ia_GetNextRequest(FILE*,FLAGSTORE);  /* Returns a pair! */
+
+#endif
diff --git a/test/spass/iaparser.c b/test/spass/iaparser.c
new file mode 100644
index 0000000000000000000000000000000000000000..4fa8697954a6ef20ea365094f830cf02c20cf218
--- /dev/null
+++ b/test/spass/iaparser.c
@@ -0,0 +1,1773 @@
+/* A Bison parser, made from iaparser.y, by GNU bison 1.75.  */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 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, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Written by Richard Stallman by simplifying the original so called
+   ``semantic'' parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON	1
+
+/* Pure parsers.  */
+#define YYPURE	0
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+/* If NAME_PREFIX is specified substitute the variables and functions
+   names.  */
+#define yyparse ia_parse
+#define yylex   ia_lex
+#define yyerror ia_error
+#define yylval  ia_lval
+#define yychar  ia_char
+#define yydebug ia_debug
+#define yynerrs ia_nerrs
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     IA_AND = 258,
+     IA_EQUAL = 259,
+     IA_EQUIV = 260,
+     IA_EXISTS = 261,
+     IA_FALSE = 262,
+     IA_FORALL = 263,
+     IA_IMPLIED = 264,
+     IA_IMPLIES = 265,
+     IA_NOT = 266,
+     IA_OR = 267,
+     IA_PROVE = 268,
+     IA_TRUE = 269,
+     IA_NUM = 270,
+     IA_ID = 271
+   };
+#endif
+#define IA_AND 258
+#define IA_EQUAL 259
+#define IA_EQUIV 260
+#define IA_EXISTS 261
+#define IA_FALSE 262
+#define IA_FORALL 263
+#define IA_IMPLIED 264
+#define IA_IMPLIES 265
+#define IA_NOT 266
+#define IA_OR 267
+#define IA_PROVE 268
+#define IA_TRUE 269
+#define IA_NUM 270
+#define IA_ID 271
+
+
+
+
+/* Copy the first part of user declarations.  */
+#line 48 "iaparser.y"
+
+
+#include "flags.h"
+#include "ia.h"
+#include "symbol.h"
+#include "term.h"
+#include "foldfg.h"
+#include "clause.h"
+
+extern NAT dfg_LINENUMBER;    /* Defined in dfgparser.y */
+LIST       ia_PROOFREQUEST;   /* A pair! */
+FLAGSTORE  ia_FLAGS;
+
+void yyerror(const char*);
+int  yylex(void);		/* Defined in iascanner.l */
+
+static SYMBOL ia_Symbol(char*, NAT);
+static TERM   ia_CreateQuantifier(SYMBOL, LIST, TERM);
+
+static __inline__ void  ia_StringFree(char* String)
+{
+  memory_Free(String, sizeof(char)*(strlen(String)+1));
+}
+
+static __inline__ TERM ia_TermCreate(char* Name, LIST Arguments)
+/* Look up the symbol, check its arity and create the term */
+{
+  return term_Create(ia_Symbol(Name,list_Length(Arguments)), Arguments);
+}
+
+/**************************************************************/
+/* Functions to check the arity of symbols                    */
+/**************************************************************/
+
+static void ia_SymCheck(SYMBOL, NAT);
+
+/**************************************************************/
+/* Functions that handle variable names                       */
+/**************************************************************/
+
+/* List of quantified variables in the current input formula. */
+/* This list is used to find symbols that by mistake weren't  */
+/* declared in the symbol declaration section                 */
+/* --> free variables                                         */
+/* This is a list of lists, since each time a quantifier is   */
+/* reached, a new list is added to the global list.           */
+static LIST ia_VARLIST;
+static BOOL ia_VARDECL;
+
+static void   ia_VarStart(void);
+static void   ia_VarStop(void);
+static void   ia_VarBacktrack(void);
+static void   ia_VarCheck(void);
+static SYMBOL ia_VarLookup(char*);
+
+#define YY_INPUT(buf,result,max_size) \
+{ \
+  int c = getc(ia_in); \
+  result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \
+}
+
+#define YYERROR_VERBOSE
+
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+#ifndef YYSTYPE
+#line 113 "iaparser.y"
+typedef union {
+  int       number;
+  char*     string;
+  SYMBOL    symbol;
+  TERM      term;
+  LIST      list;
+} yystype;
+/* Line 193 of /opt/gnu//share/bison/yacc.c.  */
+#line 187 "iaparser.c"
+# define YYSTYPE yystype
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+#ifndef YYLTYPE
+typedef struct yyltype
+{
+  int first_line;
+  int first_column;
+  int last_line;
+  int last_column;
+} yyltype;
+# define YYLTYPE yyltype
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 213 of /opt/gnu//share/bison/yacc.c.  */
+#line 208 "iaparser.c"
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# if YYSTACK_USE_ALLOCA
+#  define YYSTACK_ALLOC alloca
+# else
+#  ifndef YYSTACK_USE_ALLOCA
+#   if defined (alloca) || defined (_ALLOCA_H)
+#    define YYSTACK_ALLOC alloca
+#   else
+#    ifdef __GNUC__
+#     define YYSTACK_ALLOC __builtin_alloca
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning. */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+#  if defined (__STDC__) || defined (__cplusplus)
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   define YYSIZE_T size_t
+#  endif
+#  define YYSTACK_ALLOC malloc
+#  define YYSTACK_FREE free
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+     && (! defined (__cplusplus) \
+	 || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  short yyss;
+  YYSTYPE yyvs;
+  };
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (short) + sizeof (YYSTYPE))				\
+      + YYSTACK_GAP_MAX)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  register YYSIZE_T yyi;		\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];	\
+	}					\
+      while (0)
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)					\
+    do									\
+      {									\
+	YYSIZE_T yynewbytes;						\
+	YYCOPY (&yyptr->Stack, Stack, yysize);				\
+	Stack = &yyptr->Stack;						\
+	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX;	\
+	yyptr += yynewbytes / sizeof (*yyptr);				\
+      }									\
+    while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+   typedef signed char yysigned_char;
+#else
+   typedef short yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL  4
+#define YYLAST   83
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS  23
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS  16
+/* YYNRULES -- Number of rules. */
+#define YYNRULES  36
+/* YYNRULES -- Number of states. */
+#define YYNSTATES  77
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   271
+
+#define YYTRANSLATE(X) \
+  ((unsigned)(X) <= YYMAXUTOK ? yytranslate[X] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const unsigned char yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+      17,    19,     2,     2,    18,     2,    20,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,    21,     2,    22,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const unsigned char yyprhs[] =
+{
+       0,     0,     3,     4,    14,    16,    20,    22,    24,    26,
+      31,    38,    43,    48,    49,    50,    61,    62,    63,    74,
+      76,    78,    80,    82,    84,    86,    88,    90,    92,    94,
+      96,   100,   102,   107,   110,   114,   116
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+      24,     0,    -1,    -1,    13,    17,    26,    18,    37,    18,
+      15,    19,    20,    -1,    26,    -1,    25,    18,    26,    -1,
+      34,    -1,    14,    -1,     7,    -1,    11,    17,    26,    19,
+      -1,    31,    17,    26,    18,    26,    19,    -1,    32,    17,
+      25,    19,    -1,    34,    17,    25,    19,    -1,    -1,    -1,
+      33,    17,    21,    27,    35,    28,    22,    18,    26,    19,
+      -1,    -1,    -1,    34,    17,    21,    29,    35,    30,    22,
+      18,    26,    19,    -1,     4,    -1,     5,    -1,     9,    -1,
+      10,    -1,     3,    -1,    12,    -1,     6,    -1,     8,    -1,
+      16,    -1,    15,    -1,    36,    -1,    35,    18,    36,    -1,
+      34,    -1,    34,    17,    34,    19,    -1,    21,    22,    -1,
+      21,    38,    22,    -1,    34,    -1,    38,    18,    34,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const unsigned char yyrline[] =
+{
+       0,   136,   136,   137,   149,   150,   153,   154,   155,   156,
+     158,   160,   162,   164,   165,   164,   170,   171,   170,   179,
+     180,   181,   182,   185,   186,   189,   190,   193,   194,   197,
+     198,   201,   211,   232,   233,   236,   237
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE
+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "IA_AND", "IA_EQUAL", "IA_EQUIV", 
+  "IA_EXISTS", "IA_FALSE", "IA_FORALL", "IA_IMPLIED", "IA_IMPLIES", 
+  "IA_NOT", "IA_OR", "IA_PROVE", "IA_TRUE", "IA_NUM", "IA_ID", "'('", 
+  "','", "')'", "'.'", "'['", "']'", "$accept", "proofrequest", 
+  "termlist", "term", "@1", "@2", "@3", "@4", "binsymbol", "nsymbol", 
+  "quantsymbol", "id", "qtermlist", "qterm", "labellistopt", "labellist", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const unsigned short yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,    40,    44,    41,
+      46,    91,    93
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const unsigned char yyr1[] =
+{
+       0,    23,    24,    24,    25,    25,    26,    26,    26,    26,
+      26,    26,    26,    27,    28,    26,    29,    30,    26,    31,
+      31,    31,    31,    32,    32,    33,    33,    34,    34,    35,
+      35,    36,    36,    37,    37,    38,    38
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const unsigned char yyr2[] =
+{
+       0,     2,     0,     9,     1,     3,     1,     1,     1,     4,
+       6,     4,     4,     0,     0,    10,     0,     0,    10,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       3,     1,     4,     2,     3,     1,     3
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const unsigned char yydefact[] =
+{
+       2,     0,     0,     0,     1,    23,    19,    20,    25,     8,
+      26,    21,    22,     0,    24,     7,    28,    27,     0,     0,
+       0,     0,     6,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     4,    13,    16,     0,     9,    33,
+      35,     0,     0,     0,     0,    11,     0,     0,    12,     0,
+      34,     0,     0,     5,    31,    14,    29,    17,    36,     0,
+      10,     0,     0,     0,     0,     3,     0,    30,     0,     0,
+      32,     0,     0,     0,     0,    15,    18
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yysigned_char yydefgoto[] =
+{
+      -1,     2,    33,    34,    46,    63,    47,    64,    19,    20,
+      21,    22,    55,    56,    31,    41
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -29
+static const yysigned_char yypact[] =
+{
+     -12,    12,    35,     0,   -29,   -29,   -29,   -29,   -29,   -29,
+     -29,   -29,   -29,    19,   -29,   -29,   -29,   -29,    20,    22,
+      40,    41,    42,     0,    31,     0,     0,    43,    39,    18,
+       8,    38,    44,     7,   -29,   -29,   -29,     9,   -29,   -29,
+     -29,    -5,    46,     0,     0,   -29,    16,    16,   -29,    16,
+     -29,    47,    48,   -29,    53,    45,   -29,    45,   -29,    51,
+     -29,    16,    16,    50,    52,   -29,    54,   -29,    57,    58,
+     -29,     0,     0,    59,    60,   -29,   -29
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yysigned_char yypgoto[] =
+{
+     -29,   -29,    37,    -3,   -29,   -29,   -29,   -29,   -29,   -29,
+     -29,   -28,    30,    21,   -29,   -29
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, parse error.  */
+#define YYTABLE_NINF -1
+static const unsigned char yytable[] =
+{
+      18,     1,    40,     5,     6,     7,     8,     9,    10,    11,
+      12,    13,    14,    49,    15,    16,    17,    50,    54,    54,
+      29,    58,    32,    16,    17,    44,    45,    44,    48,     3,
+      39,    16,    17,    66,    54,     4,    23,    38,    24,    25,
+      52,    53,     5,     6,     7,     8,     9,    10,    11,    12,
+      13,    14,    30,    15,    16,    17,    42,    26,    27,    28,
+      36,    51,    43,    62,    35,    37,    59,    60,    73,    74,
+      61,    65,    68,    70,    69,    71,    72,    57,    75,    76,
+       0,     0,     0,    67
+};
+
+static const yysigned_char yycheck[] =
+{
+       3,    13,    30,     3,     4,     5,     6,     7,     8,     9,
+      10,    11,    12,    18,    14,    15,    16,    22,    46,    47,
+      23,    49,    25,    15,    16,    18,    19,    18,    19,    17,
+      22,    15,    16,    61,    62,     0,    17,    19,    18,    17,
+      43,    44,     3,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,    21,    14,    15,    16,    18,    17,    17,    17,
+      21,    15,    18,    18,    21,    28,    19,    19,    71,    72,
+      17,    20,    22,    19,    22,    18,    18,    47,    19,    19,
+      -1,    -1,    -1,    62
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const unsigned char yystos[] =
+{
+       0,    13,    24,    17,     0,     3,     4,     5,     6,     7,
+       8,     9,    10,    11,    12,    14,    15,    16,    26,    31,
+      32,    33,    34,    17,    18,    17,    17,    17,    17,    26,
+      21,    37,    26,    25,    26,    21,    21,    25,    19,    22,
+      34,    38,    18,    18,    18,    19,    27,    29,    19,    18,
+      22,    15,    26,    26,    34,    35,    36,    35,    34,    19,
+      19,    17,    18,    28,    30,    20,    34,    36,    22,    22,
+      19,    18,    18,    26,    26,    19,    19
+};
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		-2
+#define YYEOF		0
+
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT		goto yyabortlab
+#define YYERROR		goto yyerrlab1
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+
+#define YYFAIL		goto yyerrlab
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)					\
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    {								\
+      yychar = (Token);						\
+      yylval = (Value);						\
+      yychar1 = YYTRANSLATE (yychar);				\
+      YYPOPSTACK;						\
+      goto yybackup;						\
+    }								\
+  else								\
+    { 								\
+      yyerror ("syntax error: cannot back up");			\
+      YYERROR;							\
+    }								\
+while (0)
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+   are run).  */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)           \
+  Current.first_line   = Rhs[1].first_line;      \
+  Current.first_column = Rhs[1].first_column;    \
+  Current.last_line    = Rhs[N].last_line;       \
+  Current.last_column  = Rhs[N].last_column;
+#endif
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#define YYLEX	yylex ()
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)			\
+do {						\
+  if (yydebug)					\
+    YYFPRINTF Args;				\
+} while (0)
+# define YYDSYMPRINT(Args)			\
+do {						\
+  if (yydebug)					\
+    yysymprint Args;				\
+} while (0)
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YYDSYMPRINT(Args)
+#endif /* !YYDEBUG */
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef	YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#if YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined (__GLIBC__) && defined (_STRING_H)
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+static YYSIZE_T
+#   if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+#   else
+yystrlen (yystr)
+     const char *yystr;
+#   endif
+{
+  register const char *yys = yystr;
+
+  while (*yys++ != '\0')
+    continue;
+
+  return yys - yystr - 1;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+static char *
+#   if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+#   else
+yystpcpy (yydest, yysrc)
+     char *yydest;
+     const char *yysrc;
+#   endif
+{
+  register char *yyd = yydest;
+  register const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+#endif /* !YYERROR_VERBOSE */
+
+
+
+#if YYDEBUG
+/*-----------------------------.
+| Print this symbol on YYOUT.  |
+`-----------------------------*/
+
+static void
+#if defined (__STDC__) || defined (__cplusplus)
+yysymprint (FILE* yyout, int yytype, YYSTYPE yyvalue)
+#else
+yysymprint (yyout, yytype, yyvalue)
+    FILE* yyout;
+    int yytype;
+    YYSTYPE yyvalue;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvalue;
+
+  if (yytype < YYNTOKENS)
+    {
+      YYFPRINTF (yyout, "token %s (", yytname[yytype]);
+# ifdef YYPRINT
+      YYPRINT (yyout, yytoknum[yytype], yyvalue);
+# endif
+    }
+  else
+    YYFPRINTF (yyout, "nterm %s (", yytname[yytype]);
+
+  switch (yytype)
+    {
+      default:
+        break;
+    }
+  YYFPRINTF (yyout, ")");
+}
+#endif /* YYDEBUG. */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+static void
+#if defined (__STDC__) || defined (__cplusplus)
+yydestruct (int yytype, YYSTYPE yyvalue)
+#else
+yydestruct (yytype, yyvalue)
+    int yytype;
+    YYSTYPE yyvalue;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvalue;
+
+  switch (yytype)
+    {
+      default:
+        break;
+    }
+}
+
+
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+   into yyparse.  The argument should have type void *.
+   It should actually point to an object.
+   Grammar actions can access the variable by casting it
+   to the proper pointer type.  */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+#  define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+#  define YYPARSE_PARAM_DECL
+# else
+#  define YYPARSE_PARAM_ARG YYPARSE_PARAM
+#  define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+# endif
+#else /* !YYPARSE_PARAM */
+# define YYPARSE_PARAM_ARG
+# define YYPARSE_PARAM_DECL
+#endif /* !YYPARSE_PARAM */
+
+/* Prevent warning if -Wstrict-prototypes.  */
+#ifdef __GNUC__
+# ifdef YYPARSE_PARAM
+int yyparse (void *);
+# else
+int yyparse (void);
+# endif
+#endif
+
+
+/* The lookahead symbol.  */
+int yychar;
+
+/* The semantic value of the lookahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of parse errors so far.  */
+int yynerrs;
+
+
+int
+yyparse (YYPARSE_PARAM_ARG)
+     YYPARSE_PARAM_DECL
+{
+  
+  register int yystate;
+  register int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Lookahead token as an internal (translated) token number.  */
+  int yychar1 = 0;
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  short	yyssa[YYINITDEPTH];
+  short *yyss = yyssa;
+  register short *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  register YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK   (yyvsp--, yyssp--)
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
+  /* When reducing, the number of symbols on the RHS of the reduced
+     rule.  */
+  int yylen;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed. so pushing a state here evens the stacks.
+     */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyssp >= yyss + yystacksize - 1)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+	/* Give user a chance to reallocate the stack. Use copies of
+	   these so that the &'s don't force the real ones into
+	   memory.  */
+	YYSTYPE *yyvs1 = yyvs;
+	short *yyss1 = yyss;
+
+
+	/* Each stack pointer address is followed by the size of the
+	   data in use in that stack, in bytes.  This used to be a
+	   conditional around just the two extra args, but that might
+	   be undefined if yyoverflow is a macro.  */
+	yyoverflow ("parser stack overflow",
+		    &yyss1, yysize * sizeof (*yyssp),
+		    &yyvs1, yysize * sizeof (*yyvsp),
+
+		    &yystacksize);
+
+	yyss = yyss1;
+	yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyoverflowlab;
+# else
+      /* Extend the stack our own way.  */
+      if (yystacksize >= YYMAXDEPTH)
+	goto yyoverflowlab;
+      yystacksize *= 2;
+      if (yystacksize > YYMAXDEPTH)
+	yystacksize = YYMAXDEPTH;
+
+      {
+	short *yyss1 = yyss;
+	union yyalloc *yyptr =
+	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+	if (! yyptr)
+	  goto yyoverflowlab;
+	YYSTACK_RELOCATE (yyss);
+	YYSTACK_RELOCATE (yyvs);
+
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+		  (unsigned long int) yystacksize));
+
+      if (yyssp >= yyss + yystacksize - 1)
+	YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state.  */
+/* Read a lookahead token if we need one and don't already have one.  */
+/* yyresume: */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* yychar is either YYEMPTY or YYEOF
+     or a valid token in external form.  */
+
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  /* Convert token to internal form (in yychar1) for indexing tables with.  */
+
+  if (yychar <= 0)		/* This means end of input.  */
+    {
+      yychar1 = 0;
+      yychar = YYEOF;		/* Don't call YYLEX any more.  */
+
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yychar1 = YYTRANSLATE (yychar);
+
+      /* We have to keep this `#if YYDEBUG', since we use variables
+	 which are defined only if `YYDEBUG' is set.  */
+      YYDPRINTF ((stderr, "Next token is "));
+      YYDSYMPRINT ((stderr, yychar1, yylval));
+      YYDPRINTF ((stderr, "\n"));
+    }
+
+  /* If the proper action on seeing token YYCHAR1 is to reduce or to
+     detect an error, take that action.  */
+  yyn += yychar1;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yychar1)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+	goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Shift the lookahead token.  */
+  YYDPRINTF ((stderr, "Shifting token %d (%s), ",
+	      yychar, yytname[yychar1]));
+
+  /* Discard the token being shifted unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  *++yyvsp = yylval;
+
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+
+
+#if YYDEBUG
+  /* We have to keep this `#if YYDEBUG', since we use variables which
+     are defined only if `YYDEBUG' is set.  */
+  if (yydebug)
+    {
+      int yyi;
+
+      YYFPRINTF (stderr, "Reducing via rule %d (line %d), ",
+		 yyn - 1, yyrline[yyn]);
+
+      /* Print the symbols being reduced, and their result.  */
+      for (yyi = yyprhs[yyn]; yyrhs[yyi] >= 0; yyi++)
+	YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
+      YYFPRINTF (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+    }
+#endif
+  switch (yyn)
+    {
+        case 2:
+#line 136 "iaparser.y"
+    { YYABORT; }
+    break;
+
+  case 3:
+#line 137 "iaparser.y"
+    {
+					  ia_VarCheck();
+					  ia_PROOFREQUEST = list_PairCreate(yyvsp[-6].term,yyvsp[-4].list);
+					  flag_SetFlagValue(ia_FLAGS,flag_TIMELIMIT,yyvsp[-2].number);
+					  YYACCEPT;
+                                        }
+    break;
+
+  case 4:
+#line 149 "iaparser.y"
+    { yyval.list = list_List(yyvsp[0].term); }
+    break;
+
+  case 5:
+#line 150 "iaparser.y"
+    { yyval.list = list_Nconc(yyvsp[-2].list, list_List(yyvsp[0].term)); }
+    break;
+
+  case 6:
+#line 153 "iaparser.y"
+    { yyval.term = ia_TermCreate(yyvsp[0].string, list_Nil()); }
+    break;
+
+  case 7:
+#line 154 "iaparser.y"
+    { yyval.term = term_Create(fol_True(),list_Nil()); }
+    break;
+
+  case 8:
+#line 155 "iaparser.y"
+    { yyval.term = term_Create(fol_False(),list_Nil()); }
+    break;
+
+  case 9:
+#line 157 "iaparser.y"
+    { yyval.term = term_Create(fol_Not(),list_List(yyvsp[-1].term)); }
+    break;
+
+  case 10:
+#line 159 "iaparser.y"
+    { yyval.term = term_Create(yyvsp[-5].symbol, list_Cons(yyvsp[-3].term, list_List(yyvsp[-1].term))); }
+    break;
+
+  case 11:
+#line 161 "iaparser.y"
+    { yyval.term = term_Create(yyvsp[-3].symbol, yyvsp[-1].list); }
+    break;
+
+  case 12:
+#line 163 "iaparser.y"
+    { yyval.term = ia_TermCreate(yyvsp[-3].string, yyvsp[-1].list); }
+    break;
+
+  case 13:
+#line 164 "iaparser.y"
+    { ia_VarStart(); }
+    break;
+
+  case 14:
+#line 165 "iaparser.y"
+    { ia_VarStop(); }
+    break;
+
+  case 15:
+#line 167 "iaparser.y"
+    { ia_VarBacktrack();
+				  yyval.term = ia_CreateQuantifier(yyvsp[-9].symbol,yyvsp[-5].list,yyvsp[-1].term);
+				}
+    break;
+
+  case 16:
+#line 170 "iaparser.y"
+    { ia_VarStart(); }
+    break;
+
+  case 17:
+#line 171 "iaparser.y"
+    { ia_VarStop(); }
+    break;
+
+  case 18:
+#line 173 "iaparser.y"
+    { misc_StartUserErrorReport();
+				  misc_UserErrorReport("\n Line %d: SPASS can't handle the quantifier %s.\n", dfg_LINENUMBER, yyvsp[-9].string);
+				  misc_FinishUserErrorReport();
+				}
+    break;
+
+  case 19:
+#line 179 "iaparser.y"
+    { yyval.symbol = fol_Equality(); }
+    break;
+
+  case 20:
+#line 180 "iaparser.y"
+    { yyval.symbol = fol_Equiv();    }
+    break;
+
+  case 21:
+#line 181 "iaparser.y"
+    { yyval.symbol = fol_Implied();  }
+    break;
+
+  case 22:
+#line 182 "iaparser.y"
+    { yyval.symbol = fol_Implies();  }
+    break;
+
+  case 23:
+#line 185 "iaparser.y"
+    { yyval.symbol = fol_And(); }
+    break;
+
+  case 24:
+#line 186 "iaparser.y"
+    { yyval.symbol = fol_Or();  }
+    break;
+
+  case 25:
+#line 189 "iaparser.y"
+    { yyval.symbol = fol_Exist(); }
+    break;
+
+  case 26:
+#line 190 "iaparser.y"
+    { yyval.symbol = fol_All(); }
+    break;
+
+  case 27:
+#line 193 "iaparser.y"
+    { yyval.string = yyvsp[0].string; }
+    break;
+
+  case 28:
+#line 194 "iaparser.y"
+    { yyval.string = string_IntToString(yyvsp[0].number); }
+    break;
+
+  case 29:
+#line 197 "iaparser.y"
+    { yyval.list = list_List(yyvsp[0].term); }
+    break;
+
+  case 30:
+#line 198 "iaparser.y"
+    { yyval.list = list_Nconc(yyvsp[-2].list, list_List(yyvsp[0].term)); }
+    break;
+
+  case 31:
+#line 201 "iaparser.y"
+    { SYMBOL s = ia_Symbol(yyvsp[0].string,0);
+					  if (!symbol_IsVariable(s)) {
+					    misc_StartUserErrorReport();
+					    misc_UserErrorReport("\n Line %d: %s",dfg_LINENUMBER,
+								 symbol_Name(s));
+					    misc_UserErrorReport(" is not a variable.\n");
+					    misc_FinishUserErrorReport();
+					  }
+					  yyval.term = term_Create(s, list_Nil());
+					}
+    break;
+
+  case 32:
+#line 211 "iaparser.y"
+    { SYMBOL p, v;
+					  p = ia_Symbol(yyvsp[-3].string, 1);
+					  if (!symbol_IsPredicate(p)) {
+					    misc_StartUserErrorReport();
+					    misc_UserErrorReport("\n Line %d: %s",dfg_LINENUMBER,
+								 symbol_Name(p));
+					    misc_UserErrorReport(" is not a predicate.\n");
+					    misc_FinishUserErrorReport();
+					  }
+					  v = ia_Symbol(yyvsp[-1].string, 0);
+					  if (!symbol_IsVariable(v)) {
+					    misc_StartUserErrorReport();
+					    misc_UserErrorReport("\n Line %d: %s",dfg_LINENUMBER,
+								 symbol_Name(v));
+					    misc_UserErrorReport(" is not a variable.\n");
+					    misc_FinishUserErrorReport();
+					  }
+					  yyval.term = term_Create(p, list_List(term_Create(v,list_Nil())));
+					}
+    break;
+
+  case 33:
+#line 232 "iaparser.y"
+    { yyval.list = list_Nil(); }
+    break;
+
+  case 34:
+#line 233 "iaparser.y"
+    { yyval.list = yyvsp[-1].list; }
+    break;
+
+  case 35:
+#line 236 "iaparser.y"
+    { yyval.list = list_List(yyvsp[0].string); }
+    break;
+
+  case 36:
+#line 237 "iaparser.y"
+    { yyval.list = list_Nconc(yyvsp[-2].list, list_List(yyvsp[0].string)); }
+    break;
+
+
+    }
+
+/* Line 1016 of /opt/gnu//share/bison/yacc.c.  */
+#line 1290 "iaparser.c"
+
+  yyvsp -= yylen;
+  yyssp -= yylen;
+
+
+#if YYDEBUG
+  if (yydebug)
+    {
+      short *yyssp1 = yyss - 1;
+      YYFPRINTF (stderr, "state stack now");
+      while (yyssp1 != yyssp)
+	YYFPRINTF (stderr, " %d", *++yyssp1);
+      YYFPRINTF (stderr, "\n");
+    }
+#endif
+
+  *++yyvsp = yyval;
+
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if YYERROR_VERBOSE
+      yyn = yypact[yystate];
+
+      if (YYPACT_NINF < yyn && yyn < YYLAST)
+	{
+	  YYSIZE_T yysize = 0;
+	  int yytype = YYTRANSLATE (yychar);
+	  char *yymsg;
+	  int yyx, yycount;
+
+	  yycount = 0;
+	  /* Start YYX at -YYN if negative to avoid negative indexes in
+	     YYCHECK.  */
+	  for (yyx = yyn < 0 ? -yyn : 0;
+	       yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
+	    if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+	      yysize += yystrlen (yytname[yyx]) + 15, yycount++;
+	  yysize += yystrlen ("parse error, unexpected ") + 1;
+	  yysize += yystrlen (yytname[yytype]);
+	  yymsg = (char *) YYSTACK_ALLOC (yysize);
+	  if (yymsg != 0)
+	    {
+	      char *yyp = yystpcpy (yymsg, "parse error, unexpected ");
+	      yyp = yystpcpy (yyp, yytname[yytype]);
+
+	      if (yycount < 5)
+		{
+		  yycount = 0;
+		  for (yyx = yyn < 0 ? -yyn : 0;
+		       yyx < (int) (sizeof (yytname) / sizeof (char *));
+		       yyx++)
+		    if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+		      {
+			const char *yyq = ! yycount ? ", expecting " : " or ";
+			yyp = yystpcpy (yyp, yyq);
+			yyp = yystpcpy (yyp, yytname[yyx]);
+			yycount++;
+		      }
+		}
+	      yyerror (yymsg);
+	      YYSTACK_FREE (yymsg);
+	    }
+	  else
+	    yyerror ("parse error; also virtual memory exhausted");
+	}
+      else
+#endif /* YYERROR_VERBOSE */
+	yyerror ("parse error");
+    }
+  goto yyerrlab1;
+
+
+/*----------------------------------------------------.
+| yyerrlab1 -- error raised explicitly by an action.  |
+`----------------------------------------------------*/
+yyerrlab1:
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse lookahead token after an
+	 error, discard it.  */
+
+      /* Return failure if at end of input.  */
+      if (yychar == YYEOF)
+        {
+	  /* Pop the error token.  */
+          YYPOPSTACK;
+	  /* Pop the rest of the stack.  */
+	  while (yyssp > yyss)
+	    {
+	      YYDPRINTF ((stderr, "Error: popping "));
+	      YYDSYMPRINT ((stderr,
+			    yystos[*yyssp],
+			    *yyvsp));
+	      YYDPRINTF ((stderr, "\n"));
+	      yydestruct (yystos[*yyssp], *yyvsp);
+	      YYPOPSTACK;
+	    }
+	  YYABORT;
+        }
+
+      YYDPRINTF ((stderr, "Discarding token %d (%s).\n",
+		  yychar, yytname[yychar1]));
+      yydestruct (yychar1, yylval);
+      yychar = YYEMPTY;
+    }
+
+  /* Else will try to reuse lookahead token after shifting the error
+     token.  */
+
+  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+	{
+	  yyn += YYTERROR;
+	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+	    {
+	      yyn = yytable[yyn];
+	      if (0 < yyn)
+		break;
+	    }
+	}
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+	YYABORT;
+
+      YYDPRINTF ((stderr, "Error: popping "));
+      YYDSYMPRINT ((stderr,
+		    yystos[*yyssp], *yyvsp));
+      YYDPRINTF ((stderr, "\n"));
+
+      yydestruct (yystos[yystate], *yyvsp);
+      yyvsp--;
+      yystate = *--yyssp;
+
+
+#if YYDEBUG
+      if (yydebug)
+	{
+	  short *yyssp1 = yyss - 1;
+	  YYFPRINTF (stderr, "Error: state stack now");
+	  while (yyssp1 != yyssp)
+	    YYFPRINTF (stderr, " %d", *++yyssp1);
+	  YYFPRINTF (stderr, "\n");
+	}
+#endif
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  YYDPRINTF ((stderr, "Shifting error token, "));
+
+  *++yyvsp = yylval;
+
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#ifndef yyoverflow
+/*----------------------------------------------.
+| yyoverflowlab -- parser overflow comes here.  |
+`----------------------------------------------*/
+yyoverflowlab:
+  yyerror ("parser stack overflow");
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+  return yyresult;
+}
+
+
+#line 240 "iaparser.y"
+
+
+
+void yyerror(const char *s)
+{
+  misc_StartUserErrorReport();
+  misc_UserErrorReport("\n Line %i: %s\n", dfg_LINENUMBER, s);
+  misc_FinishUserErrorReport();
+
+}
+
+LIST ia_GetNextRequest(FILE* Input, FLAGSTORE Flags)
+/**************************************************************
+  INPUT:   An input file containing one proof request from KIV.
+  RETURNS: The proof request as pair (formula, labellist),
+           list_Nil(), if EOF was reached.
+  EFFECT:  Reads ONE proof request from the file.
+           <Input> may also be a UNIX pipe.
+***************************************************************/
+{
+  extern FILE* ia_in;  /* defined in kivscanner */
+
+  ia_in           = Input;
+  ia_PROOFREQUEST = list_Nil();
+  ia_FLAGS        = Flags;
+  ia_parse();
+  
+  return ia_PROOFREQUEST;
+}
+
+
+/**************************************************************/
+/* Static Functions                                           */
+/**************************************************************/
+
+static SYMBOL ia_Symbol(char* Name, NAT Arity)
+/**************************************************************
+  INPUT:   The name of a symbol and the actual arity of the symbol.
+  RETURNS: The corresponding SYMBOL.
+  EFFECT:  This function checks if the <Name> was declared as
+           symbol or variable. If not, an error message is printed
+	   to stderr.
+	   The <Name> is deleted.
+***************************************************************/
+{
+  SYMBOL symbol;
+
+  symbol = symbol_Lookup(Name);
+  if (symbol != 0) {
+    ia_StringFree(Name);
+    ia_SymCheck(symbol, Arity); /* Check the arity */
+  } else {
+    /* Variable */
+    if (Arity > 0) {
+      misc_StartUserErrorReport();
+      misc_UserErrorReport("\n Line %d: Undefined symbol %s.\n",dfg_LINENUMBER,Name);
+      misc_FinishUserErrorReport();
+    }
+    symbol = ia_VarLookup(Name);
+  }
+  return symbol;
+}
+
+
+static TERM ia_CreateQuantifier(SYMBOL Symbol, LIST VarTermList, TERM Term)
+/**************************************************************
+  INPUT:   A quantifier symbol, a list possibly containing sorts,
+           and a term.
+  RETURNS: The created quantifier term..
+***************************************************************/
+{
+  LIST varlist, sortlist, scan;
+  TERM helpterm;
+
+  /* First collect the variable symbols in varlist and the sorts in sortlist */
+  varlist = sortlist = list_Nil();
+  for ( ; !list_Empty(VarTermList); VarTermList = list_Pop(VarTermList)) {
+    helpterm = list_Car(VarTermList);
+    if (term_IsVariable(helpterm)) {
+      varlist = list_Nconc(varlist, list_List((POINTER)term_TopSymbol(helpterm)));
+      term_Delete(helpterm);
+    } else {
+      SYMBOL var = term_TopSymbol(term_FirstArgument(helpterm));
+      varlist  = list_Nconc(varlist, list_List((POINTER)var));
+      sortlist = list_Nconc(sortlist, list_List(helpterm));
+    }
+  }
+
+  varlist = list_PointerDeleteDuplicates(varlist);
+  /* Now create terms from the variables */
+  for (scan = varlist; !list_Empty(scan); scan = list_Cdr(scan))
+    list_Rplaca(scan, term_Create((SYMBOL)list_Car(scan), list_Nil()));
+
+  if (!list_Empty(sortlist)) {
+    if (symbol_Equal(fol_All(), Symbol)) {
+      /* The conjunction of all sortterms implies the Term */
+      if (symbol_Equal(fol_Or(), term_TopSymbol(Term))) {
+	/* Special treatment if <Term> is a term with "or" like */
+	/* in clauses: add all sort terms negated to the args    */
+	/* of the "or" */
+	for (scan = sortlist; !list_Empty(scan); scan = list_Cdr(scan))
+	  /* Negate the sort terms */
+	  list_Rplaca(scan, term_Create(fol_Not(), list_List(list_Car(scan))));
+	sortlist = list_Nconc(sortlist, term_ArgumentList(Term));
+	term_RplacArgumentList(Term, sortlist);
+      } else {
+	/* No "or" term, so build the implication term */
+	if (list_Empty(list_Cdr(sortlist))) {
+	  /* Only one sort term */
+	  list_Rplacd(sortlist, list_List(Term));
+	  Term = term_Create(fol_Implies(), sortlist);
+	} else {
+	  /* More than one sort term */
+	  helpterm = term_Create(fol_And(), sortlist);
+	  Term = term_Create(fol_Implies(), list_Cons(helpterm, list_List(Term)));
+	}
+      }
+    } else if (symbol_Equal(fol_Exist(), Symbol)) {
+      /* Quantify the conjunction of all sort terms and <Term> */
+      if (symbol_Equal(fol_And(), term_TopSymbol(Term))) {
+	/* Special treatment if <Term> has an "and" as top symbol: */
+	/* just add the sort terms to the args of the "and".       */
+	sortlist = list_Nconc(sortlist, term_ArgumentList(Term));
+	term_RplacArgumentList(Term, sortlist);
+      } else {
+	sortlist = list_Nconc(sortlist, list_List(Term));
+	Term = term_Create(fol_And(), sortlist);
+      }
+    }
+  }
+  helpterm = fol_CreateQuantifier(Symbol, varlist, list_List(Term));
+  return helpterm;
+}
+
+
+/**************************************************************/
+/* Functions for the Symbol Table                             */
+/**************************************************************/
+
+static void ia_SymCheck(SYMBOL Symbol, NAT Arity)
+/**************************************************************
+  INPUT:   A symbol and the current arity of this symbol.
+  RETURNS: Nothing.
+  EFFECT:  This function compares the previous arity of 'Symbol'
+           with the actual 'Arity'. If these values differ
+	   a warning is printed to stderr and the program exits.
+***************************************************************/
+{
+  /* Check if the specified arity corresponds with the actual arity */
+  if (symbol_Arity(Symbol) != symbol_ArbitraryArity() &&
+      symbol_Arity(Symbol) != Arity) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n Line %u: Symbol %s", dfg_LINENUMBER, symbol_Name(Symbol));
+    misc_UserErrorReport(" was declared with arity %u.\n", symbol_Arity(Symbol));
+    misc_FinishUserErrorReport();
+  }
+}
+
+
+/**************************************************************/
+/* Functions for the Variable Table                           */
+/**************************************************************/
+  
+typedef struct {
+  char*  name;
+  SYMBOL symbol;
+} IA_VARENTRY, *IA_VAR;
+
+static __inline__ char* ia_VarName(IA_VAR Entry)
+{
+  return Entry->name;
+}
+
+static __inline__ SYMBOL ia_VarSymbol(IA_VAR Entry)
+{
+  return Entry->symbol;
+}
+
+static __inline__ IA_VAR ia_VarCreate(void)
+{
+  return (IA_VAR) memory_Malloc(sizeof(IA_VARENTRY));
+}
+
+static void ia_VarFree(IA_VAR Entry)
+{
+  ia_StringFree(Entry->name);
+  memory_Free(Entry, sizeof(IA_VARENTRY));
+}
+
+static void ia_VarStart(void)
+{
+  ia_VARLIST = list_Push(list_Nil(), ia_VARLIST);
+  ia_VARDECL = TRUE;
+}
+
+static void ia_VarStop(void)
+{
+  ia_VARDECL = FALSE;
+}
+
+static void ia_VarBacktrack(void)
+{
+  list_DeleteWithElement(list_Top(ia_VARLIST), (void (*)(POINTER)) ia_VarFree);
+  ia_VARLIST = list_Pop(ia_VARLIST);
+}
+
+static void ia_VarCheck(void)
+/* Should be called after a complete clause or formula was parsed */
+{
+  if (!list_Empty(ia_VARLIST)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In ia_VarCheck: List of variables should be empty!\n");
+    misc_FinishErrorReport();
+  }
+  symbol_ResetStandardVarCounter();
+}
+
+static SYMBOL ia_VarLookup(char* Name)
+/**************************************************************
+  INPUT:   A variable name.
+  RETURNS: The corresponding variable symbol.
+  EFFECT:  If the variable name was quantified before, the
+           corresponding symbol is returned and the <Name> is freed.
+	   If the variable name was not quantified, and <ia_VARDECL>
+	   is TRUE, a new variable is created, else an error
+	   message is printed and the program exits.
+***************************************************************/
+{
+  LIST   scan, scan2;
+  SYMBOL symbol;
+
+  symbol = symbol_Null();
+
+  scan  = ia_VARLIST;
+  scan2 = list_Nil();
+  while (!list_Empty(scan) && list_Empty(scan2)) {
+    scan2 = list_Car(scan);
+    while (!list_Empty(scan2) &&
+	   !string_Equal(ia_VarName(list_Car(scan2)), Name))
+      scan2 = list_Cdr(scan2);
+    scan = list_Cdr(scan);
+  }
+
+  if (!list_Empty(scan2)) {
+    /* Found variable */
+    ia_StringFree(Name);
+    symbol = ia_VarSymbol(list_Car(scan2));
+  } else {
+    /* Variable not found */
+    if (ia_VARDECL) {
+      IA_VAR newEntry = ia_VarCreate();
+      newEntry->name   = Name;
+      newEntry->symbol = symbol_CreateStandardVariable();
+      /* Add <newentry> to the first list in ia_VARLIST */
+      list_Rplaca(ia_VARLIST, list_Cons(newEntry,list_Car(ia_VARLIST)));
+      symbol = ia_VarSymbol(newEntry);
+    } else {
+      misc_StartUserErrorReport();
+      misc_UserErrorReport("\n Line %u: Free Variable %s.\n", dfg_LINENUMBER, Name);
+      misc_FinishUserErrorReport();
+    }
+  }
+  return symbol;
+}
+
diff --git a/test/spass/iaparser.h b/test/spass/iaparser.h
new file mode 100644
index 0000000000000000000000000000000000000000..32fb09369d1cf32aa8d3a023aacd2988092f8f46
--- /dev/null
+++ b/test/spass/iaparser.h
@@ -0,0 +1,87 @@
+/* A Bison parser, made from iaparser.y, by GNU bison 1.75.  */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 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, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+#ifndef BISON_IAPARSER_H
+# define BISON_IAPARSER_H
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     IA_AND = 258,
+     IA_EQUAL = 259,
+     IA_EQUIV = 260,
+     IA_EXISTS = 261,
+     IA_FALSE = 262,
+     IA_FORALL = 263,
+     IA_IMPLIED = 264,
+     IA_IMPLIES = 265,
+     IA_NOT = 266,
+     IA_OR = 267,
+     IA_PROVE = 268,
+     IA_TRUE = 269,
+     IA_NUM = 270,
+     IA_ID = 271
+   };
+#endif
+#define IA_AND 258
+#define IA_EQUAL 259
+#define IA_EQUIV 260
+#define IA_EXISTS 261
+#define IA_FALSE 262
+#define IA_FORALL 263
+#define IA_IMPLIED 264
+#define IA_IMPLIES 265
+#define IA_NOT 266
+#define IA_OR 267
+#define IA_PROVE 268
+#define IA_TRUE 269
+#define IA_NUM 270
+#define IA_ID 271
+
+
+
+
+#ifndef YYSTYPE
+#line 113 "iaparser.y"
+typedef union {
+  int       number;
+  char*     string;
+  SYMBOL    symbol;
+  TERM      term;
+  LIST      list;
+} yystype;
+/* Line 1281 of /opt/gnu//share/bison/yacc.c.  */
+#line 80 "iaparser.h"
+# define YYSTYPE yystype
+#endif
+
+extern YYSTYPE ia_lval;
+
+
+#endif /* not BISON_IAPARSER_H */
+
diff --git a/test/spass/iascanner.c b/test/spass/iascanner.c
new file mode 100644
index 0000000000000000000000000000000000000000..9677a81efe343cb75a39bdf30381d68ac445eb1e
--- /dev/null
+++ b/test/spass/iascanner.c
@@ -0,0 +1,1991 @@
+#define yy_create_buffer ia__create_buffer
+#define yy_delete_buffer ia__delete_buffer
+#define yy_scan_buffer ia__scan_buffer
+#define yy_scan_string ia__scan_string
+#define yy_scan_bytes ia__scan_bytes
+#define yy_flex_debug ia__flex_debug
+#define yy_init_buffer ia__init_buffer
+#define yy_flush_buffer ia__flush_buffer
+#define yy_load_buffer_state ia__load_buffer_state
+#define yy_switch_to_buffer ia__switch_to_buffer
+#define yyin ia_in
+#define yyleng ia_leng
+#define yylex ia_lex
+#define yyout ia_out
+#define yyrestart ia_restart
+#define yytext ia_text
+
+#line 19 "iascanner.c"
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header$
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif	/* __STDC__ */
+#endif	/* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator).  This
+ * avoids problems with code like:
+ *
+ * 	if ( condition_holds )
+ *		yyless( 5 );
+ *	else
+ *		do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+		*yy_cp = yy_hold_char; \
+		YY_RESTORE_YY_MORE_OFFSET \
+		yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+	};
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1;		/* whether we need to initialize */
+static int yy_start = 0;	/* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! yy_current_buffer ) \
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	yy_current_buffer->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! yy_current_buffer ) \
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	yy_current_buffer->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+
+#define yywrap() 1
+#define YY_SKIP_YYWRAP
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+static yyconst short yy_nxt[][24] =
+    {
+    {
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0
+    },
+
+    {
+        3,    4,    5,    6,    7,    8,    9,   10,    9,   11,
+       12,   13,    9,    9,   14,   15,   16,    9,    9,    9,
+       17,    9,    9,    9
+    },
+
+    {
+        3,    4,    5,    6,    7,    8,    9,   10,    9,   11,
+       12,   13,    9,    9,   14,   15,   16,    9,    9,    9,
+       17,    9,    9,    9
+    },
+
+    {
+       -3,   -3,   -3,   -3,   -3,   -3,   -3,   -3,   -3,   -3,
+
+       -3,   -3,   -3,   -3,   -3,   -3,   -3,   -3,   -3,   -3,
+       -3,   -3,   -3,   -3
+    },
+
+    {
+        3,   -4,   -4,   -4,   -4,   -4,   -4,   -4,   -4,   -4,
+       -4,   -4,   -4,   -4,   -4,   -4,   -4,   -4,   -4,   -4,
+       -4,   -4,   -4,   -4
+    },
+
+    {
+        3,   -5,   18,   -5,   -5,   -5,   -5,   -5,   -5,   -5,
+       -5,   -5,   -5,   -5,   -5,   -5,   -5,   -5,   -5,   -5,
+       -5,   -5,   -5,   -5
+    },
+
+    {
+        3,   -6,   -6,   -6,   -6,   -6,   -6,   -6,   -6,   -6,
+       -6,   -6,   -6,   -6,   -6,   -6,   -6,   -6,   -6,   -6,
+
+       -6,   -6,   -6,   -6
+    },
+
+    {
+        3,   -7,   -7,   -7,   -7,   -7,   -7,   -7,   -7,   -7,
+       -7,   -7,   -7,   -7,   -7,   -7,   -7,   -7,   -7,   -7,
+       -7,   -7,   -7,   -7
+    },
+
+    {
+        3,   -8,   -8,   -8,   -8,   19,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,   -9,   -9,   -9,   -9,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+
+    },
+
+    {
+        3,  -10,  -10,  -10,  -10,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   21,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -11,  -11,  -11,  -11,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   22,   20,   20,
+       20,   20,   20,   23
+    },
+
+    {
+        3,  -12,  -12,  -12,  -12,   20,   20,   24,   20,   20,
+       20,   20,   20,   20,   20,   25,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -13,  -13,  -13,  -13,   20,   20,   20,   20,   20,
+
+       20,   20,   20,   26,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -14,  -14,  -14,  -14,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   27,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -15,  -15,  -15,  -15,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   28,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -16,  -16,  -16,  -16,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   29,   20,
+
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -17,  -17,  -17,  -17,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   30,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -18,   18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,
+      -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,
+      -18,  -18,  -18,  -18
+    },
+
+    {
+        3,  -19,  -19,  -19,  -19,   19,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+
+    },
+
+    {
+        3,  -20,  -20,  -20,  -20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -21,  -21,  -21,  -21,   20,   20,   20,   31,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -22,  -22,  -22,  -22,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   32,   20,   20
+    },
+
+    {
+        3,  -23,  -23,  -23,  -23,   20,   20,   20,   20,   20,
+
+       20,   33,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -24,  -24,  -24,  -24,   20,   20,   20,   20,   20,
+       20,   20,   34,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -25,  -25,  -25,  -25,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   35,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -26,  -26,  -26,  -26,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   36,   20,   20,   20,
+
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -27,  -27,  -27,  -27,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       37,   20,   20,   20
+    },
+
+    {
+        3,  -28,  -28,  -28,  -28,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -29,  -29,  -29,  -29,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   38,   20,   20,   20,   20,
+       20,   20,   20,   20
+
+    },
+
+    {
+        3,  -30,  -30,  -30,  -30,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   39,   20,   20
+    },
+
+    {
+        3,  -31,  -31,  -31,  -31,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -32,  -32,  -32,  -32,   20,   20,   40,   20,   20,
+       20,   41,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -33,  -33,  -33,  -33,   20,   20,   20,   20,   20,
+
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   42,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -34,  -34,  -34,  -34,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   43,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -35,  -35,  -35,  -35,   20,   20,   44,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -36,  -36,  -36,  -36,   20,   20,   20,   20,   20,
+       20,   20,   45,   20,   20,   20,   20,   20,   20,   20,
+
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -37,  -37,  -37,  -37,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -38,  -38,  -38,  -38,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   46,   20
+    },
+
+    {
+        3,  -39,  -39,  -39,  -39,   20,   20,   20,   20,   47,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+
+    },
+
+    {
+        3,  -40,  -40,  -40,  -40,   20,   20,   20,   20,   20,
+       20,   20,   48,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -41,  -41,  -41,  -41,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   49,   20
+    },
+
+    {
+        3,  -42,  -42,  -42,  -42,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       50,   20,   20,   20
+    },
+
+    {
+        3,  -43,  -43,  -43,  -43,   20,   20,   20,   20,   51,
+
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -44,  -44,  -44,  -44,   20,   20,   20,   20,   20,
+       20,   20,   52,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -45,  -45,  -45,  -45,   20,   20,   20,   20,   20,
+       20,   53,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -46,  -46,  -46,  -46,   20,   20,   20,   20,   54,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -47,  -47,  -47,  -47,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -48,  -48,  -48,  -48,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -49,  -49,  -49,  -49,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+
+    },
+
+    {
+        3,  -50,  -50,  -50,  -50,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   55,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -51,  -51,  -51,  -51,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -52,  -52,  -52,  -52,   20,   20,   20,   20,   20,
+       20,   20,   56,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -53,  -53,  -53,  -53,   20,   20,   20,   20,   57,
+
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -54,  -54,  -54,  -54,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -55,  -55,  -55,  -55,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -56,  -56,  -56,  -56,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -57,  -57,  -57,  -57,   20,   20,   20,   58,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   59,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -58,  -58,  -58,  -58,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+    },
+
+    {
+        3,  -59,  -59,  -59,  -59,   20,   20,   20,   20,   20,
+       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+       20,   20,   20,   20
+
+    },
+
+    } ;
+
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	yytext_ptr = yy_bp; \
+	yyleng = (int) (yy_cp - yy_bp); \
+	yy_hold_char = *yy_cp; \
+	*yy_cp = '\0'; \
+	yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 19
+#define YY_END_OF_BUFFER 20
+static yyconst short int yy_accept[60] =
+    {   0,
+        0,    0,   20,   18,   15,   16,   17,   13,   14,   14,
+       14,   14,   14,   14,   14,   14,   14,   15,   13,   14,
+       14,   14,   14,   14,   14,   14,   14,   10,   14,   14,
+        1,   14,   14,   14,   14,   14,    9,   14,   14,   14,
+       14,   14,   14,   14,   14,   14,   11,    2,    3,   14,
+        5,   14,   14,   12,    4,    6,   14,    7,    8
+    } ;
+
+static yyconst int yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    1,    1,    1,    1,    1,    1,    1,    4,
+        4,    1,    1,    4,    4,    4,    1,    5,    5,    5,
+        5,    5,    5,    5,    5,    5,    5,    1,    1,    1,
+        1,    1,    1,    1,    6,    6,    6,    6,    6,    6,
+        6,    6,    6,    6,    6,    6,    6,    6,    6,    6,
+        6,    6,    6,    6,    6,    6,    6,    6,    6,    6,
+        4,    1,    4,    1,    6,    1,    7,    6,    6,    8,
+
+        9,   10,    6,    6,   11,    6,    6,   12,   13,   14,
+       15,   16,   17,   18,   19,   20,   21,   22,    6,   23,
+        6,    6,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "iascanner.l"
+#define INITIAL 0
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *        SCANNER FOR SPASS INTERACTIVE MODULE            * */
+/* *                                                        * */
+/* *  $Module:   KIV                                        * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1997, 1998, 1999, 2001                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+/* $RCSfile$ */
+#line 49 "iascanner.l"
+
+#include <ctype.h>   /* for isprint */
+#include <errno.h>
+#include "misc.h"
+#include "memory.h"
+#include "symbol.h"
+#include "term.h"
+#include "ia.h"
+#include "iaparser.h"
+
+extern NAT dfg_LINENUMBER;  /* defined in dfgparser.y */
+
+/* Force the scanner to read the input character by character */
+#define YY_ALWAYS_INTERACTIVE 1
+#define YY_NO_UNPUT 1
+#line 803 "iascanner.c"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines.  This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( yy_current_buffer->yy_is_interactive ) \
+		{ \
+		int c = '*', n; \
+		for ( n = 0; n < max_size && \
+			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+			buf[n] = (char) c; \
+		if ( c == '\n' ) \
+			buf[n++] = (char) c; \
+		if ( c == EOF && ferror( yyin ) ) \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+		result = n; \
+		} \
+	else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+		  && ferror( yyin ) ) \
+		YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	YY_USER_ACTION
+
+YY_DECL
+	{
+	register yy_state_type yy_current_state;
+	register char *yy_cp, *yy_bp;
+	register int yy_act;
+
+#line 68 "iascanner.l"
+
+
+#line 957 "iascanner.c"
+
+	if ( yy_init )
+		{
+		yy_init = 0;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! yy_start )
+			yy_start = 1;	/* first start state */
+
+		if ( ! yyin )
+			yyin = stdin;
+
+		if ( ! yyout )
+			yyout = stdout;
+
+		if ( ! yy_current_buffer )
+			yy_current_buffer =
+				yy_create_buffer( yyin, YY_BUF_SIZE );
+
+		yy_load_buffer_state();
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+		yy_cp = yy_c_buf_p;
+
+		/* Support of yytext. */
+		*yy_cp = yy_hold_char;
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = yy_start;
+yy_match:
+		while ( (yy_current_state = yy_nxt[yy_current_state][yy_ec[YY_SC_TO_UI(*yy_cp)]]) > 0 )
+			++yy_cp;
+
+		yy_current_state = -yy_current_state;
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+
+		YY_DO_BEFORE_ACTION;
+
+
+do_action:	/* This label is used only to access EOF actions. */
+
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+case 1:
+YY_RULE_SETUP
+#line 70 "iascanner.l"
+return IA_AND;
+	YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 71 "iascanner.l"
+return IA_EQUAL;
+	YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 72 "iascanner.l"
+return IA_EQUIV;
+	YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 73 "iascanner.l"
+return IA_EXISTS;
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 74 "iascanner.l"
+return IA_FALSE;
+	YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 75 "iascanner.l"
+return IA_FORALL;
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 76 "iascanner.l"
+return IA_IMPLIED;
+	YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 77 "iascanner.l"
+return IA_IMPLIES;
+	YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 78 "iascanner.l"
+return IA_NOT;
+	YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 79 "iascanner.l"
+return IA_OR;
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 80 "iascanner.l"
+return IA_TRUE;
+	YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 81 "iascanner.l"
+return IA_PROVE;
+	YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 82 "iascanner.l"
+{ unsigned long n;
+                                  errno = 0;
+                                  n = strtoul(yytext, NULL, 10);
+				  if (errno != 0 || n > INT_MAX) {
+                                    misc_StartUserErrorReport();
+                                    misc_UserErrorReport("\n Number too big in line %d.\n",
+							 dfg_LINENUMBER);
+                                    misc_FinishUserErrorReport();
+                                  }
+                                  ia_lval.number = (int) n;
+                                  return IA_NUM;
+                                }
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 94 "iascanner.l"
+{ ia_lval.string = (char*) memory_Malloc(yyleng+1);
+				  strcpy(ia_lval.string, yytext);
+                                  return IA_ID;
+                                }
+	YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 98 "iascanner.l"
+/* ignore */
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 99 "iascanner.l"
+dfg_LINENUMBER++;
+	YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 100 "iascanner.l"
+return yytext[0];
+	YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 101 "iascanner.l"
+{ misc_StartUserErrorReport();
+                                  misc_UserErrorReport("\n Illegal character '");
+				  if (isprint((int)yytext[0]))
+				    misc_UserErrorReport("%c",yytext[0]);
+				  else
+				    misc_UserErrorReport("\\x%x", (unsigned int) yytext[0]);
+				  misc_UserErrorReport("' in line %d.\n", dfg_LINENUMBER);
+                                  misc_FinishUserErrorReport();
+                                }
+	YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 111 "iascanner.l"
+ECHO;
+	YY_BREAK
+#line 1130 "iascanner.c"
+			case YY_STATE_EOF(INITIAL):
+				yyterminate();
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = yy_hold_char;
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed yyin at a new source and called
+			 * yylex().  If so, then we have to assure
+			 * consistency between yy_current_buffer and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			yy_n_chars = yy_current_buffer->yy_n_chars;
+			yy_current_buffer->yy_input_file = yyin;
+			yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state();
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++yy_c_buf_p;
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = yy_c_buf_p;
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer() )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				yy_did_buffer_switch_on_eof = 0;
+
+				if ( yywrap() )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * yytext, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				yy_c_buf_p =
+					yytext_ptr + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state();
+
+				yy_cp = yy_c_buf_p;
+				yy_bp = yytext_ptr + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				yy_c_buf_p =
+				&yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+				yy_current_state = yy_get_previous_state();
+
+				yy_cp = yy_c_buf_p;
+				yy_bp = yytext_ptr + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+	} /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+	{
+	register char *dest = yy_current_buffer->yy_ch_buf;
+	register char *source = yytext_ptr;
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( yy_current_buffer->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+	else
+		{
+		int num_to_read =
+			yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+			YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = yy_current_buffer;
+
+			int yy_c_buf_p_offset =
+				(int) (yy_c_buf_p - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					yy_flex_realloc( (void *) b->yy_ch_buf,
+							 b->yy_buf_size + 2 );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = yy_current_buffer->yy_buf_size -
+						number_to_move - 1;
+#endif
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+			yy_n_chars, num_to_read );
+
+		yy_current_buffer->yy_n_chars = yy_n_chars;
+		}
+
+	if ( yy_n_chars == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			yyrestart( yyin );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			yy_current_buffer->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	yy_n_chars += number_to_move;
+	yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+	yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+	yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+	return ret_val;
+	}
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+	{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+
+	yy_current_state = yy_start;
+
+	for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+		{
+		yy_current_state = yy_nxt[yy_current_state][(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1)];
+		}
+
+	return yy_current_state;
+	}
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+	{
+	register int yy_is_jam;
+
+	yy_current_state = yy_nxt[yy_current_state][1];
+	yy_is_jam = (yy_current_state <= 0);
+
+	return yy_is_jam ? 0 : yy_current_state;
+	}
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+	{
+	register char *yy_cp = yy_c_buf_p;
+
+	/* undo effects of setting up yytext */
+	*yy_cp = yy_hold_char;
+
+	if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		register int number_to_move = yy_n_chars + 2;
+		register char *dest = &yy_current_buffer->yy_ch_buf[
+					yy_current_buffer->yy_buf_size + 2];
+		register char *source =
+				&yy_current_buffer->yy_ch_buf[number_to_move];
+
+		while ( source > yy_current_buffer->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		yy_current_buffer->yy_n_chars =
+			yy_n_chars = yy_current_buffer->yy_buf_size;
+
+		if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+
+	yytext_ptr = yy_bp;
+	yy_hold_char = *yy_cp;
+	yy_c_buf_p = yy_cp;
+	}
+#endif	/* ifndef YY_NO_UNPUT */
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+	{
+	int c;
+
+	*yy_c_buf_p = yy_hold_char;
+
+	if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+			/* This was really a NUL. */
+			*yy_c_buf_p = '\0';
+
+		else
+			{ /* need more input */
+			int offset = yy_c_buf_p - yytext_ptr;
+			++yy_c_buf_p;
+
+			switch ( yy_get_next_buffer() )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					yyrestart( yyin );
+
+					/* fall through */
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( yywrap() )
+						return EOF;
+
+					if ( ! yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput();
+#else
+					return input();
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					yy_c_buf_p = yytext_ptr + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) yy_c_buf_p;	/* cast for 8-bit char's */
+	*yy_c_buf_p = '\0';	/* preserve yytext */
+	yy_hold_char = *++yy_c_buf_p;
+
+
+	return c;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+	{
+	if ( ! yy_current_buffer )
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+	yy_init_buffer( yy_current_buffer, input_file );
+	yy_load_buffer_state();
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+	{
+	if ( yy_current_buffer == new_buffer )
+		return;
+
+	if ( yy_current_buffer )
+		{
+		/* Flush out information for old buffer. */
+		*yy_c_buf_p = yy_hold_char;
+		yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+		yy_current_buffer->yy_n_chars = yy_n_chars;
+		}
+
+	yy_current_buffer = new_buffer;
+	yy_load_buffer_state();
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (yywrap()) processing, but the only time this flag
+	 * is looked at is after yywrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	yy_did_buffer_switch_on_eof = 1;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+	{
+	yy_n_chars = yy_current_buffer->yy_n_chars;
+	yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+	yyin = yy_current_buffer->yy_input_file;
+	yy_hold_char = *yy_c_buf_p;
+	}
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+	{
+	YY_BUFFER_STATE b;
+
+	b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	yy_init_buffer( b, file );
+
+	return b;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+	{
+	if ( ! b )
+		return;
+
+	if ( b == yy_current_buffer )
+		yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		yy_flex_free( (void *) b->yy_ch_buf );
+
+	yy_flex_free( (void *) b );
+	}
+
+
+#ifndef YY_ALWAYS_INTERACTIVE
+#ifndef YY_NEVER_INTERACTIVE
+extern int isatty YY_PROTO(( int ));
+#endif
+#endif
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+	{
+	yy_flush_buffer( b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+	b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+	b->yy_is_interactive = 0;
+#else
+	b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+	{
+	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == yy_current_buffer )
+		yy_load_buffer_state();
+	}
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+	{
+	YY_BUFFER_STATE b;
+
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	yy_switch_to_buffer( b );
+
+	return b;
+	}
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+	{
+	int len;
+	for ( len = 0; yy_str[len]; ++len )
+		;
+
+	return yy_scan_bytes( yy_str, len );
+	}
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+	{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = len + 2;
+	buf = (char *) yy_flex_alloc( n );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+	for ( i = 0; i < len; ++i )
+		buf[i] = bytes[i];
+
+	buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = yy_scan_buffer( buf, n );
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+	}
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+	{
+	if ( yy_start_stack_ptr >= yy_start_stack_depth )
+		{
+		yy_size_t new_size;
+
+		yy_start_stack_depth += YY_START_STACK_INCR;
+		new_size = yy_start_stack_depth * sizeof( int );
+
+		if ( ! yy_start_stack )
+			yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+		else
+			yy_start_stack = (int *) yy_flex_realloc(
+					(void *) yy_start_stack, new_size );
+
+		if ( ! yy_start_stack )
+			YY_FATAL_ERROR(
+			"out of memory expanding start-condition stack" );
+		}
+
+	yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+	BEGIN(new_state);
+	}
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+	{
+	if ( --yy_start_stack_ptr < 0 )
+		YY_FATAL_ERROR( "start-condition stack underflow" );
+
+	BEGIN(yy_start_stack[yy_start_stack_ptr]);
+	}
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+	{
+	return yy_start_stack[yy_start_stack_ptr - 1];
+	}
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+	{
+	(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+	}
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+		yytext[yyleng] = yy_hold_char; \
+		yy_c_buf_p = yytext + n; \
+		yy_hold_char = *yy_c_buf_p; \
+		*yy_c_buf_p = '\0'; \
+		yyleng = n; \
+		} \
+	while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+	{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+	}
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+	{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+	}
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+	{
+	return (void *) malloc( size );
+	}
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+	{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+	}
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+	{
+	free( ptr );
+	}
+
+#if YY_MAIN
+int main()
+	{
+	yylex();
+	return 0;
+	}
+#endif
+#line 111 "iascanner.l"
+
diff --git a/test/spass/kbo.c b/test/spass/kbo.c
new file mode 100644
index 0000000000000000000000000000000000000000..c598cbe55564d17fafad01f2bd35bf3cfb7ea5df
--- /dev/null
+++ b/test/spass/kbo.c
@@ -0,0 +1,593 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *         EXTENDED KNUTH BENDIX ORDERING                 * */
+/* *                                                        * */
+/* *  $Module:   KBO                                        * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "kbo.h"
+#include "order.h"
+
+const int kbo_MINWEIGHT = 1;
+
+/**************************************************************/
+/*  Functions to implement an order on terms                  */
+/**************************************************************/
+
+static int kbo_ContCompVarCondAndWeightIntern(CONTEXT Context, TERM Term, int Index)
+/**************************************************************
+  INPUT:   
+  EFFECT:  
+***************************************************************/
+{
+  int Weight;
+
+  Weight = 0;
+  Term   = cont_Deref(&Context,Term);
+
+  if (term_IsStandardVariable(Term)) {
+    ord_VARCOUNT[term_TopSymbol(Term)][Index]++;
+    Weight += kbo_MINWEIGHT;
+  }
+  else {
+    LIST Scan;
+    Weight += symbol_Weight(term_TopSymbol(Term));
+    for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan))
+      Weight += kbo_ContCompVarCondAndWeightIntern(Context, list_Car(Scan), Index);
+  }
+
+  return Weight;
+}
+
+static int kbo_ContCompVarCondAndWeight(CONTEXT Context1, TERM Term1, BOOL *VarCond1, 
+					CONTEXT Context2, TERM Term2, BOOL *VarCond2)
+/**************************************************************
+  INPUT:   Two contexts, two terms and two pointers to booleans.
+  EFFECT:  Sets the booleans with respect to the kbo variable condition.
+           Computes the kbo weight difference.
+	   The terms are interpreted with respect to the bindings in the respective
+	   contexts.
+***************************************************************/
+{
+  SYMBOL MaxVar1,MaxVar2;
+  int    i,Weight;
+
+  *VarCond1 = *VarCond2 = TRUE;
+  MaxVar1   = cont_TermMaxVar(Context1,Term1);
+  MaxVar2   = cont_TermMaxVar(Context2,Term2);
+
+  if (MaxVar1 < MaxVar2)
+    MaxVar1 = MaxVar2;
+
+  for (i = 0; i <= MaxVar1; i++) {
+    ord_VARCOUNT[i][0] = 0;
+    ord_VARCOUNT[i][1] = 0;
+  }
+
+  Weight = kbo_ContCompVarCondAndWeightIntern(Context1, Term1, 0);
+  Weight = Weight - kbo_ContCompVarCondAndWeightIntern(Context2, Term2, 1);
+
+  for (i = 0; i <= MaxVar1; i++) {
+    if (ord_VARCOUNT[i][0] < ord_VARCOUNT[i][1]) {
+      *VarCond1 = FALSE;
+      if (!*VarCond2)
+	return Weight;
+    }
+    else if (ord_VARCOUNT[i][0] > ord_VARCOUNT[i][1]) {
+      *VarCond2 = FALSE;
+      if (!*VarCond1)
+	return Weight;
+    }
+  }
+  return Weight;  
+}
+
+
+static int kbo_CompVarCondAndWeight(TERM Term1, BOOL *VarCond1, TERM Term2, BOOL *VarCond2)
+/**************************************************************
+  INPUT:   Two terms and two pointers to booleans.
+  EFFECT:  Sets the booleans with respect to the kbo variable condition.
+           Computes the kbo weight difference.
+***************************************************************/
+{
+  SYMBOL MaxVar1,MaxVar2;
+  TERM   Term;
+  LIST   Scan;
+  int    i,Stack,Weight;
+
+  *VarCond1 = *VarCond2 = TRUE;
+  MaxVar1   = term_MaxVar(Term1);
+  MaxVar2   = term_MaxVar(Term2);
+  Stack     = stack_Bottom();
+  Weight    = 0;
+
+  if (MaxVar1 < MaxVar2)
+    MaxVar1 = MaxVar2;
+
+  for (i = 0; i <= MaxVar1; i++) {
+    ord_VARCOUNT[i][0] = 0;
+    ord_VARCOUNT[i][1] = 0;
+  }
+
+  Term = Term1;
+  if (term_IsStandardVariable(Term)) {
+    ord_VARCOUNT[term_TopSymbol(Term)][0]++;
+    Weight += kbo_MINWEIGHT;
+  }
+  else {
+    Weight += symbol_Weight(term_TopSymbol(Term));
+    if (term_IsComplex(Term))
+      stack_Push(term_ArgumentList(Term));
+  }
+  while (!stack_Empty(Stack)) {
+    Scan = stack_Top();
+    Term = (TERM)list_Car(Scan);
+    stack_RplacTop(list_Cdr(Scan));
+    if (term_IsStandardVariable(Term)) {
+      Weight += kbo_MINWEIGHT;
+      ord_VARCOUNT[term_TopSymbol(Term)][0]++;
+    }
+    else {
+      Weight += symbol_Weight(term_TopSymbol(Term));
+      if (term_IsComplex(Term))
+	stack_Push(term_ArgumentList(Term));
+    }
+    while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+      stack_Pop();
+  }
+
+  Term = Term2;
+  if (term_IsStandardVariable(Term)) {
+    Weight -= kbo_MINWEIGHT;
+    ord_VARCOUNT[term_TopSymbol(Term)][1]++;
+  }
+  else {
+    Weight -= symbol_Weight(term_TopSymbol(Term));
+    if (term_IsComplex(Term))
+      stack_Push(term_ArgumentList(Term));
+  }
+  while (!stack_Empty(Stack)) {
+    Scan = stack_Top();
+    Term = (TERM)list_Car(Scan);
+    stack_RplacTop(list_Cdr(Scan));
+    if (term_IsStandardVariable(Term)) {
+      Weight -= kbo_MINWEIGHT;
+      ord_VARCOUNT[term_TopSymbol(Term)][1]++;
+    }
+    else {
+      Weight -= symbol_Weight(term_TopSymbol(Term));
+      if (term_IsComplex(Term))
+	stack_Push(term_ArgumentList(Term));
+    }
+    while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+      stack_Pop();
+  }
+
+  for (i = 0; i <= MaxVar1; i++) {
+    if (ord_VARCOUNT[i][0] < ord_VARCOUNT[i][1]) {
+      *VarCond1 = FALSE;
+      if (!*VarCond2)
+	return Weight;
+    }
+   if (ord_VARCOUNT[i][0] > ord_VARCOUNT[i][1]) {
+      *VarCond2 = FALSE;
+      if (!*VarCond1)
+	return Weight;
+    }
+  }
+  return Weight;  
+}
+
+
+static ord_RESULT kbo_CompareStruc(TERM Term1, TERM Term2, int WeightDiff)
+/**************************************************************
+  INPUT:   Two terms where the kbo-variable condition for <Term1> and
+           <Term2> is satisfied and <WeightDiff> is the kbo weight difference
+	   between <Term1> and <Term2> 
+  RETURNS: ord_UNCOMPARABLE, if Term1 and Term2 are uncomparable
+	   ord_EQUAL,        if Term1 and Term2 are equal
+	   ord_GREATER_THAN, if Term1 is greater than Term2
+  CAUTION: The precedence from the order module is used to determine
+           the precedence of symbols!
+***************************************************************/
+{
+  LIST   Scan1,Scan2;
+  SYMBOL Top1,Top2;
+
+  Top1       = term_TopSymbol(Term1);
+  Top2       = term_TopSymbol(Term2);
+
+  if (WeightDiff > 0)
+    return ord_GREATER_THAN;
+  else 
+    if (WeightDiff == 0) {
+      if (symbol_IsStandardVariable(Top1)) {
+	if (symbol_IsStandardVariable(Top2))
+	  return ord_EQUAL;
+	else
+	  return ord_UNCOMPARABLE;
+      }
+      else
+	if (symbol_IsStandardVariable(Top2) ||
+	    symbol_PrecedenceGreater(ord_PRECEDENCE, Top1, Top2))
+	  return ord_GREATER_THAN;
+	else
+	  if (Top1 == Top2) {
+	    int    RecWeightDiff;
+	    BOOL   T1VarCond, T2VarCond;
+	    TERM   RecTerm1,RecTerm2;
+	    Scan1 = term_ArgumentList(Term1);
+	    Scan2 = term_ArgumentList(Term2);
+	    if (symbol_HasProperty(Top1,ORDRIGHT)) {
+	      int i;
+	      for (i = symbol_Arity(Top1);
+		   i > 0 && term_Equal(list_NthElement(Scan1,i),list_NthElement(Scan2,i));
+		   i--);
+	      if (i > 0) {
+		RecTerm1 = (TERM)list_NthElement(Scan1,i);
+		RecTerm2 = (TERM)list_NthElement(Scan2,i);
+	      }
+	      else
+		return ord_EQUAL;
+	    }
+	    else {	      
+	      while (!list_Empty(Scan1) && term_Equal(list_Car(Scan1),list_Car(Scan2))) {
+		Scan1 = list_Cdr(Scan1);
+		Scan2 = list_Cdr(Scan2);
+	      }
+	      if (list_Empty(Scan1)) /* Implies that list_Empty(Scan2)  */
+		return ord_EQUAL;
+	      else {
+		RecTerm1 = (TERM)list_Car(Scan1);
+		RecTerm2 = (TERM)list_Car(Scan2);
+	      }
+	    }	      
+	    RecWeightDiff =  kbo_CompVarCondAndWeight(RecTerm1,&T1VarCond,RecTerm2,&T2VarCond);
+	    if (RecWeightDiff >= 0 && T1VarCond)
+	      return kbo_CompareStruc(RecTerm1, RecTerm2, RecWeightDiff);
+	    else
+	      return ord_UNCOMPARABLE;
+	  }
+	  else
+	    return ord_UNCOMPARABLE;
+    }
+    else
+      return ord_UNCOMPARABLE;
+
+  return ord_UNCOMPARABLE;
+}
+  
+
+ord_RESULT kbo_Compare(TERM Term1, TERM Term2)
+/**************************************************************
+  INPUT:   Two terms.
+  RETURNS: ord_UNCOMPARABLE, if Term1 and Term2 are uncomparable because of
+                              different variables,
+	   ord_EQUAL,        if Term1 and Term2 are comparable and have the
+	                      same weight,
+	   ord_GREATER_THAN, if Term1 is greater than Term2 wrt the kbo with
+	                      the actual precedence and the given symbol weights,
+	   ord_SMALLER_THAN, else.
+  CAUTION: The precedence from the order module is used to determine
+           the precedence of symbols!
+***************************************************************/
+{
+  int        WeightDiff;
+  BOOL       T1VarCond, T2VarCond;
+  ord_RESULT Result;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term1) || !term_IsTerm(Term2)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In kbo_Compare:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+
+  WeightDiff =  kbo_CompVarCondAndWeight(Term1,&T1VarCond,Term2,&T2VarCond);
+
+  if (T1VarCond && !T2VarCond)
+    return kbo_CompareStruc(Term1,Term2,WeightDiff);
+
+  if (!T1VarCond && T2VarCond)
+    return ord_Not(kbo_CompareStruc(Term2,Term1,-WeightDiff));
+
+  if (T1VarCond && T2VarCond) {
+    Result = kbo_CompareStruc(Term1,Term2,WeightDiff);
+    if (Result == ord_UNCOMPARABLE)
+      return ord_Not(kbo_CompareStruc(Term2,Term1,-WeightDiff));
+    else
+      return Result;
+  }
+
+  return ord_UNCOMPARABLE;
+}
+
+static ord_RESULT kbo_ContCompareStruc(CONTEXT Context1, TERM Term1,
+				       CONTEXT Context2, TERM Term2,
+				       int WeightDiff)
+/**************************************************************
+  INPUT:   Two contexts and two terms where the kbo-variable condition
+           for <Term1> and <Term2> is satisfied and <WeightDiff> is the
+	   kbo weight difference between <Term1> and <Term2>.
+  RETURNS: ord_UNCOMPARABLE, if Term1 and Term2 are uncomparable
+	   ord_EQUAL,        if Term1 and Term2 are equal
+	   ord_GREATER_THAN, if Term1 is greater than Term2 
+	   The Terms are interpreted with respect to the contexts.
+  CAUTION: The precedence from the order module is used to determine
+           the precedence of symbols!
+***************************************************************/
+{
+  LIST   Scan1,Scan2;
+  SYMBOL Top1,Top2;
+
+  Term1      = cont_Deref(&Context1,Term1);
+  Term2      = cont_Deref(&Context2,Term2);
+  Top1       = term_TopSymbol(Term1);
+  Top2       = term_TopSymbol(Term2);
+
+  if (WeightDiff > 0)
+    return ord_GREATER_THAN;
+  else 
+    if (WeightDiff == 0) {
+      if (symbol_IsStandardVariable(Top1)) {
+	if (symbol_IsStandardVariable(Top2))
+	  return ord_EQUAL;
+	else
+	  return ord_UNCOMPARABLE;
+      }
+      else
+	if (symbol_IsStandardVariable(Top2) ||
+	    symbol_PrecedenceGreater(ord_PRECEDENCE, Top1,Top2))
+	  return ord_GREATER_THAN;
+	else
+	  if (Top1 == Top2) {
+	    int    RecWeightDiff;
+	    BOOL   T1VarCond, T2VarCond;
+	    TERM   RecTerm1,RecTerm2;
+	    Scan1 = term_ArgumentList(Term1);
+	    Scan2 = term_ArgumentList(Term2);
+	    if (symbol_HasProperty(Top1,ORDRIGHT)) {
+	      int i;
+	      for (i = symbol_Arity(Top1);
+		   i > 0 && cont_TermEqual(Context1,list_NthElement(Scan1,i),
+					   Context2,list_NthElement(Scan2,i));
+		   i--);
+	      if (i > 0) {
+		RecTerm1 = cont_Deref(&Context1,list_NthElement(Scan1,i));
+		RecTerm2 = cont_Deref(&Context2,list_NthElement(Scan2,i));
+	      }
+	      else
+		return ord_EQUAL;
+	    }
+	    else {	      
+	      while (!list_Empty(Scan1) && cont_TermEqual(Context1,list_Car(Scan1),Context2,list_Car(Scan2))) {
+		Scan1 = list_Cdr(Scan1);
+		Scan2 = list_Cdr(Scan2);
+	      }
+	      if (list_Empty(Scan1)) /* Implies that list_Empty(Scan2)  */
+		return ord_EQUAL;
+	      else {
+		RecTerm1 = cont_Deref(&Context1,list_Car(Scan1));
+		RecTerm2 = cont_Deref(&Context2,list_Car(Scan2));
+	      }
+	    }	      
+	    RecWeightDiff =  kbo_ContCompVarCondAndWeight(Context1,RecTerm1,&T1VarCond,
+							  Context2,RecTerm2,&T2VarCond);
+	    if (RecWeightDiff >= 0 && T1VarCond)
+	      return kbo_ContCompareStruc(Context1, RecTerm1, Context2, RecTerm2, RecWeightDiff);
+	    else
+	      return ord_UNCOMPARABLE;
+	  }
+	  else
+	    return ord_UNCOMPARABLE;
+    }
+    else
+      return ord_UNCOMPARABLE;
+
+  return ord_UNCOMPARABLE;
+}
+  
+
+ord_RESULT kbo_ContCompare(CONTEXT Context1, TERM Term1, CONTEXT Context2, TERM Term2)
+/**************************************************************
+  INPUT:   Two contexts and two terms.
+  RETURNS: ord_UNCOMPARABLE, if Term1 and Term2 are uncomparable because of
+                              different variables,
+	   ord_EQUAL,        if Term1 and Term2 are comparable and have the
+	                      same weight,
+	   ord_GREATER_THAN, if Term1 is greater than Term2 wrt the kbo with
+	                      the actual precedence kbo_Prec and the given 
+			      symbol_Weights,
+	   ord_SMALLER_THAN, else.
+	   The Terms are interpreted with respect to the contexts.
+  CAUTION: The precedence from the order module is used to determine
+           the precedence of symbols!
+***************************************************************/
+{
+  int        WeightDiff;
+  BOOL       T1VarCond, T2VarCond;
+  ord_RESULT Result;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term1) || !term_IsTerm(Term2)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In kbo_Compare:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+
+  WeightDiff =  kbo_ContCompVarCondAndWeight(Context1, Term1, &T1VarCond, Context2, Term2, &T2VarCond);
+
+  if (T1VarCond && !T2VarCond)
+    return kbo_ContCompareStruc(Context1,Term1,Context2,Term2,WeightDiff);
+
+  if (!T1VarCond && T2VarCond)
+    return ord_Not(kbo_ContCompareStruc(Context2,Term2,Context1,Term1,-WeightDiff));
+
+  if (T1VarCond && T2VarCond) {
+    Result = kbo_ContCompareStruc(Context1,Term1,Context2,Term2,WeightDiff);
+    if (Result == ord_UNCOMPARABLE)
+      return ord_Not(kbo_ContCompareStruc(Context2,Term2,Context1,Term1,-WeightDiff));
+    else
+      return Result;
+  }
+
+  return ord_UNCOMPARABLE;
+}
+
+static BOOL kbo_ContGreaterCompareStruc(CONTEXT Context1, TERM Term1,
+					CONTEXT Context2, TERM Term2)
+/**************************************************************
+  INPUT:   Two contexts and two terms where the kbo-variable condition
+           for <Term1> and <Term2> is satisfied as well as the
+	   weight difference between the terms is zero.
+  RETURNS: TRUE if Term1 is greater than Term2.
+	   The Terms are interpreted with respect to the contexts.
+  CAUTION: The precedence from the order module is used to determine
+           the precedence of symbols!
+***************************************************************/
+{
+  LIST   Scan1,Scan2;
+  SYMBOL Top1,Top2;
+
+  Term1      = cont_Deref(&Context1,Term1);
+  Term2      = cont_Deref(&Context2,Term2);
+  Top1       = term_TopSymbol(Term1);
+  Top2       = term_TopSymbol(Term2);
+
+  if (symbol_IsStandardVariable(Top1)) {
+    if (symbol_IsStandardVariable(Top2))
+      return FALSE;
+    else
+      return FALSE;
+  }
+  else
+    if (symbol_IsStandardVariable(Top2) ||
+	symbol_PrecedenceGreater(ord_PRECEDENCE, Top1, Top2))
+      return TRUE;
+    else
+      if (Top1 == Top2) {
+	int    RecWeightDiff;
+	BOOL   T1VarCond, T2VarCond;
+	TERM   RecTerm1,RecTerm2;
+	Scan1 = term_ArgumentList(Term1);
+	Scan2 = term_ArgumentList(Term2);
+	if (symbol_HasProperty(Top1,ORDRIGHT)) {
+	  int i;
+	  for (i = symbol_Arity(Top1);
+	       i > 0 && cont_TermEqual(Context1,list_NthElement(Scan1,i),
+				       Context2,list_NthElement(Scan2,i));
+	       i--);
+	  if (i > 0) {
+	    RecTerm1 = cont_Deref(&Context1,list_NthElement(Scan1,i));
+	    RecTerm2 = cont_Deref(&Context2,list_NthElement(Scan2,i));
+	  }
+	  else
+	    return FALSE;
+	}
+	else {	      
+	  while (!list_Empty(Scan1) && cont_TermEqual(Context1,list_Car(Scan1),Context2,list_Car(Scan2))) {
+	    Scan1 = list_Cdr(Scan1);
+	    Scan2 = list_Cdr(Scan2);
+	  }
+	  if (list_Empty(Scan1)) /* Implies that list_Empty(Scan2)  */
+	    return FALSE;
+	  else {
+	    RecTerm1 = cont_Deref(&Context1,list_Car(Scan1));
+	    RecTerm2 = cont_Deref(&Context2,list_Car(Scan2));
+	  }
+	}	      
+	RecWeightDiff =  kbo_ContCompVarCondAndWeight(Context1,RecTerm1,&T1VarCond,
+						      Context2,RecTerm2,&T2VarCond);
+
+	if (T1VarCond) {
+	  if (RecWeightDiff > 0)
+	    return TRUE;
+	  else
+	    if (RecWeightDiff == 0)
+	      return kbo_ContGreaterCompareStruc(Context1, RecTerm1, Context2, RecTerm2);
+	}
+      }
+  
+  return FALSE;
+}
+
+
+BOOL kbo_ContGreater(CONTEXT Context1, TERM Term1, CONTEXT Context2, TERM Term2)
+/**************************************************************
+  INPUT:   Two contexts and two terms.
+  RETURNS: TRUE, if Term1 is greater than Term2 wrt the kbo with
+           the actual precedence kbo_Prec and the given symbol_Weights
+  CAUTION: The precedence from the order module is used to determine
+           the precedence of symbols!
+***************************************************************/
+{
+  int        WeightDiff;
+  BOOL       T1VarCond, T2VarCond;
+
+#ifdef CHECK
+  if ((!term_IsTerm(Term1)) || (!term_IsTerm(Term2)) ) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In kbo_ContGreater:");
+    misc_ErrorReport("\n Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+
+  WeightDiff =  kbo_ContCompVarCondAndWeight(Context1, Term1, &T1VarCond, Context2, Term2, &T2VarCond);
+
+  if (T1VarCond) {
+    if (WeightDiff > 0)
+      return TRUE;
+    else
+      if (WeightDiff == 0) 
+	return kbo_ContGreaterCompareStruc(Context1,Term1,Context2,Term2);
+  }
+  return FALSE;
+}
diff --git a/test/spass/kbo.h b/test/spass/kbo.h
new file mode 100644
index 0000000000000000000000000000000000000000..00db284e8b9cca7478b1fba29fff7d3c3b8bc295
--- /dev/null
+++ b/test/spass/kbo.h
@@ -0,0 +1,67 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *         EXTENDED KNUTH BENDIX ORDERING                 * */
+/* *                                                        * */
+/* *  $Module:   KBO                                        * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 2001 MPI fuer Informatik    * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _KBO_
+#define _KBO_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "term.h"
+#include "context.h"
+#include "foldfg.h"
+#include "order.h"
+
+/**************************************************************/
+/*  FUNCTIONS                                                 */
+/**************************************************************/
+
+ord_RESULT kbo_Compare(TERM, TERM);
+ord_RESULT kbo_ContCompare(CONTEXT, TERM, CONTEXT, TERM); 
+BOOL       kbo_ContGreater(CONTEXT, TERM, CONTEXT, TERM);
+
+#endif
diff --git a/test/spass/list.c b/test/spass/list.c
new file mode 100644
index 0000000000000000000000000000000000000000..c956e1e1b7424de826781c8a0ef79cd746cb3fc5
--- /dev/null
+++ b/test/spass/list.c
@@ -0,0 +1,1660 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                     LISTS                              * */
+/* *                                                        * */
+/* *  $Module:   LIST                                       * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "list.h"
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  MEMORY MANAGEMENT                                     * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+LIST list_Copy(const LIST List)
+/**************************************************************
+  INPUT:   A List.
+  RETURNS: The copy of the list.
+  CAUTION: The entries of the list are NOT copied !
+           the function needs time O(n), where <n> is the length
+	   of the list.
+***************************************************************/
+{
+  LIST Copy;
+  LIST Scan1,Scan2;
+
+ 
+  if (list_Empty(List))
+    return list_Nil();
+
+  Copy  = list_List(list_Car(List));
+  Scan1 = Copy;
+  Scan2 = list_Cdr(List);
+
+  while (!list_Empty(Scan2)) {
+    list_Rplacd(Scan1, list_List(list_Car(Scan2)));
+    Scan1 = list_Cdr(Scan1);
+    Scan2 = list_Cdr(Scan2);
+  }
+  return Copy;
+}
+
+
+LIST list_CopyWithElement(const LIST List, POINTER (*CopyElement)(POINTER))
+/**************************************************************
+  INPUT:   A List and a copy function for the elements.
+  RETURNS: The copy of the list.
+  CAUTION: The entries of the list are NOT copied !
+           The function needs time O(n*c), where <n> is the length
+	   of the list and <c> is the time for a call of the
+	   element copy function.
+***************************************************************/
+{
+  LIST Copy;
+  LIST Scan1,Scan2;
+
+  if (list_Empty(List))
+    return list_Nil();
+
+  Copy  = list_List(CopyElement(list_Car(List)));
+  Scan1 = Copy;
+  Scan2 = list_Cdr(List);
+
+  while (!list_Empty(Scan2)) {
+    list_Rplacd(Scan1, list_List(CopyElement(list_Car(Scan2))));
+    Scan1 = list_Cdr(Scan1);
+    Scan2 = list_Cdr(Scan2);
+  }
+  return Copy;
+}
+
+
+void list_InsertNext(LIST List, POINTER Pointer)
+/**************************************************************
+  INPUT:   A list and a pointer to anything.
+  RETURNS: A list with Pointer being added at the position that
+           follows List.
+  SUMMARY: We enqueue the element at position list_Cdr(List);
+           The function needs time O(1).
+***************************************************************/
+{
+#ifdef CHECK
+  if (Pointer == NULL) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In list_InsertNext: NULL Pointer. ");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  list_Rplacd(List, list_Cons(Pointer, list_Cdr(List)));
+}
+
+
+void list_NMapCar(LIST List, POINTER (*ElementFunc)(POINTER))
+/**************************************************************
+  INPUT:   A List and a function for the elements.
+  RETURNS: The List where all elements are replaced by the result of 
+           the function calls of <ElementFunc> to the elements
+  CAUTION: The List is not copied !
+           The function needs time O(n*f), where <n> is the length
+	   of the list and <f> is the time for a call of the
+	   element function.
+***************************************************************/
+{
+  LIST Scan;
+
+  for (Scan = List; !list_Empty(Scan); Scan = list_Cdr(Scan))
+    list_Rplaca(Scan, ElementFunc(list_Car(Scan)));
+}
+
+
+void list_Apply(void (*Function)(POINTER),  LIST List)
+/**************************************************************
+  INPUT:   A non-resulting function and a list.
+  SUMMARY: Apply the function to all members of the list.
+           The function needs time O(n*f), where <n> is the length
+	   of the list and <f> is the time for a call of the
+	   element function.
+***************************************************************/
+{
+  while (!list_Empty(List)) {
+    Function(list_Car(List));
+    List = list_Cdr(List);
+  }
+}
+
+
+LIST list_Reverse(const LIST List)
+/**************************************************************
+  INPUT:   A list.
+  RETURNS: A new list where the order of the elements is reversed.
+  EFFECT:  The function needs time O(n), where <n> is the length
+           of the list.
+***************************************************************/
+{
+  LIST ReverseList;
+  LIST Scan;
+  
+  ReverseList = list_Nil();
+
+  for (Scan=List;!list_Empty(Scan);Scan=list_Cdr(Scan)) 
+    ReverseList = list_Cons(list_Car(Scan), ReverseList);
+
+  return ReverseList;
+}
+
+
+LIST list_NReverse(LIST List)
+/**************************************************************
+  INPUT:   A list
+  RETURNS: The same list with reversed order of items.
+  CAUTION: Destructive.
+           The function needs time O(n), where <n> is the length
+           of the list.
+***************************************************************/
+{
+  LIST ReverseList;
+  LIST Scan1;
+  LIST Scan2;
+  
+  ReverseList = list_Nil();
+
+  for (Scan1=List; !list_Empty(Scan1); Scan1=list_Cdr(Scan1)) 
+    ReverseList = list_Cons(list_Car(Scan1),ReverseList);
+
+  for (Scan1=List, Scan2=ReverseList;
+       !list_Empty(Scan1);
+       Scan1=list_Cdr(Scan1), Scan2=list_Cdr(Scan2)) 
+    list_Rplaca(Scan1, list_Car(Scan2));
+
+  list_Delete(ReverseList);
+  return List;
+}
+
+
+static __inline__ BOOL list_PointerLower (POINTER A, POINTER B)
+{
+  return (NAT) A < (NAT) B;
+}
+
+LIST list_PointerSort(LIST List)
+/**************************************************************
+  INPUT:   A list
+  RETURNS: The same list where the elements are sorted as pointers.
+  EFFECT:  The function needs time O(n log n), where <n> is the length
+           of the list.
+  CAUTION: Destructive.
+***************************************************************/
+{
+  return list_Sort(List, list_PointerLower);
+}
+
+
+BOOL list_SortedInOrder(LIST L, BOOL (*Test)(POINTER, POINTER)) 
+/**************************************************************
+  INPUT:   A list, and an ordering function.
+  RETURNS: TRUE, if the list is ordered with respect to the
+           ordering function, FALSE otherwise.
+  EFFECT:  The function needs time O(n), where <n> is the 
+           length of the list.
+***************************************************************/
+{
+  LIST Scan1, Scan2;
+
+  if (!(list_Empty(L) || list_Empty(list_Cdr(L)))) {
+    Scan1 = L;
+    Scan2 = list_Cdr(Scan1);
+
+    /* Scan the list. */
+    do {
+      /* If all elements are ordered, then every element  */
+      /* is <= its successor with respect to the ordering */
+      /* function.                                        */
+      /* We might have a strictly ordering Test function, */
+      /* which implements < instead of <=, so let's test  */
+      /* for equality first. */
+      if (!Test(list_Car(Scan1), list_Car(Scan2)) &&
+	  Test(list_Car(Scan2), list_Car(Scan1)))
+	/* It is really strictly greater, so return FALSE. */
+	return FALSE;
+
+      Scan1 = list_Cdr(Scan1);
+      Scan2 = list_Cdr(Scan1);
+    } while (!list_Empty(Scan2));
+  }
+
+  return TRUE;
+}
+
+
+LIST list_Merge(LIST List1, LIST List2, BOOL (*Test)(POINTER, POINTER)) 
+/**************************************************************
+  INPUT:   Two sorted lists List1 and List2, and an ordering function.
+  RETURNS: The merged list ordered with respect to the ordering function.
+  EFFECT:  The function needs time O(n), where <n> is the length of the list.
+***************************************************************/
+{
+
+  LIST Scan1, Scan2, Result, ResultStart;
+
+#ifdef CHECK
+  if (!list_SortedInOrder(List1, Test)) {
+    /* print an error message and exit */
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In list_Merge: First argument is not sorted.");
+    misc_FinishErrorReport();
+  }
+  else if (!list_SortedInOrder (List2, Test)) {
+    /* print an error message and exit */
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In list_Merge: Second argument is not sorted.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (list_Empty(List1))
+    return List2;
+
+  if (list_Empty(List2))
+    return List1;
+
+  /* This version is derived from list_NNumberMerge, but it doesn't need */
+  /* to allocate and deallocate memory, so it should be more efficient.  */
+
+  /* Use the list with the least element as result list. */
+  if (Test(list_Car(List1), list_Car(List2))) {
+    ResultStart = List1;
+    Scan1       = list_Cdr(List1);
+    Scan2       = List2;
+  }
+  else {
+    ResultStart = List2;
+    Scan1       = List1;
+    Scan2       = list_Cdr(List2);
+  }
+
+  /* Result is the last element of the merged list. */
+
+  Result = ResultStart;
+
+  while (!list_Empty(Scan1) && !list_Empty(Scan2)) {
+    /* This function doesn't implement stable merging. */
+    /* Add another test if you need it.                */
+
+    if (Test(list_Car(Scan1), list_Car(Scan2))) {
+      list_Rplacd(Result,Scan1);
+      Scan1  = list_Cdr(Scan1);
+    }
+    else {
+      list_Rplacd(Result,Scan2);
+      Scan2  = list_Cdr(Scan2);
+    }
+    Result = list_Cdr(Result);
+  }
+
+  if (list_Empty(Scan1))
+    list_Rplacd(Result, Scan2);
+  else
+    list_Rplacd(Result, Scan1);
+
+  return ResultStart;
+}
+
+
+void list_Split(LIST L, LIST *Half1, LIST *Half2) 
+/**************************************************************
+  INPUT:   A list, and two pointers to lists.
+  RETURNS: Nothing.
+  EFFECT:  The input list is split in two. <Half1> and 
+           <Half2> point to the resulting halves.
+	   The input list is destructively changed!
+	   If the list length is odd, <Half2> is assigned the
+	   bigger part. 
+	   The function needs time O(n), where <n> is the 
+           length of the input list.
+***************************************************************/
+{
+  /* Adapted code from proofcheck ... MergeSort. */
+
+  LIST SingleStep, DoubleStep, Prev;
+
+  if (list_Empty(L) || list_Empty(list_Cdr(L))) {
+    *Half1 = list_Nil();
+    *Half2 = L;
+  }
+  else {
+    /* divide list in two halves */
+    Prev = L;
+    SingleStep = list_Cdr(L);
+    DoubleStep = list_Cdr(SingleStep);
+    
+    while (!list_Empty(DoubleStep) && !list_Empty(list_Cdr(DoubleStep))) {
+      Prev       = SingleStep;
+      SingleStep = list_Cdr(SingleStep);
+      DoubleStep = list_Cdr(list_Cdr(DoubleStep));
+    }
+    
+    *Half1 = L;
+    *Half2 = SingleStep;
+    list_Rplacd(Prev, list_Nil());
+  }
+}
+
+
+LIST list_MergeSort (LIST L, BOOL (*Test) (POINTER, POINTER)) 
+/**************************************************************
+  INPUT:   A list, and an ordering function.
+  RETURNS: The list sorted with respect to the ordering function.
+  EFFECT:  The function needs time O((n log n) * t), where 
+	   <n> is the length of the input list and <t> is the
+	   execution time of the ordering function.
+***************************************************************/
+{
+  LIST Result; 
+#ifdef CHECK
+  NAT  originallength;
+
+  originallength = list_Length(L);
+#endif
+
+  /* Only sort if list has more than one element */
+  if (!list_Empty(L) && !list_Empty(list_Cdr(L))) {
+    LIST  lowerhalf;
+    LIST  greaterhalf;
+
+    LIST *lowerhalfptr;
+    LIST *greaterhalfptr;
+
+    lowerhalfptr = &lowerhalf;
+    greaterhalfptr = &greaterhalf;
+
+    list_Split(L, lowerhalfptr, greaterhalfptr);
+
+#ifdef CHECK
+    if((list_Length(lowerhalf) + list_Length(greaterhalf)) 
+       != originallength) {
+      /* output an error message and exit */
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In list_MergeSort: Split lists' total sizes");
+      misc_ErrorReport("\n don't match original list's size.");
+      misc_FinishErrorReport();
+    }
+#endif
+
+    lowerhalf   = list_MergeSort(lowerhalf, Test);
+
+    greaterhalf = list_MergeSort(greaterhalf, Test);
+
+#ifdef CHECK
+    if((list_Length(lowerhalf) + list_Length(greaterhalf)) 
+       != originallength) {
+      /* output an error message and exit */
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In list_MergeSort: Mergesorted lists' total sizes");
+      misc_ErrorReport("\n don't match original list's size.");
+      misc_FinishErrorReport();
+    }
+#endif
+
+    Result = list_Merge(lowerhalf, greaterhalf, Test);
+    
+#ifdef CHECK
+    if(list_Length(Result) != originallength) {
+      /* output an error message and exit */
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In list_MergeSort: Merged list's size doesn't match ");
+      misc_ErrorReport("\n original list's size.");
+      misc_FinishErrorReport();
+    }
+#endif
+
+  }
+  else {
+    Result = L;
+  }
+
+  return Result;
+}
+
+
+LIST list_InsertionSort(LIST List, BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+  INPUT:   A list and a 'less' function on the elements.
+  RETURNS: The same list where the elements are sorted with
+           respect to Test.
+  EFFECT:  The function needs time O(n^2*t), where <n> is the
+           length of the list and <t> is the time for the test
+	   function.
+  CAUTION: Destructive.
+***************************************************************/
+{
+  LIST Scan1,Scan2,Min;
+  POINTER Exchange;
+
+  for (Scan1=List; !list_Empty(Scan1); Scan1=list_Cdr(Scan1)) {
+    Min = Scan1;
+    for (Scan2 = list_Cdr(Scan1); !list_Empty(Scan2); Scan2 = list_Cdr(Scan2))
+      if (Test(list_Car(Scan2), list_Car(Min))) {
+	Exchange = list_Car(Min);
+	list_Rplaca(Min, list_Car(Scan2));
+	list_Rplaca(Scan2, Exchange);
+      }
+  }
+
+  return List;
+}
+
+
+LIST list_Sort(LIST List, BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+  INPUT:   A list and a 'less' function on the elements.
+  RETURNS: The same list where the elements are sorted with
+           respect to Test.
+  EFFECT:  The function needs time O((n log n) *t), where <n> 
+           is the length of the list and <t> is the time for 
+	   the test function.
+  CAUTION: Destructive.
+***************************************************************/
+{
+  LIST Result;
+
+#ifdef CHECK
+  NAT  originallength;
+
+  originallength = list_Length(List);
+#endif
+
+  Result = list_MergeSort(List, Test);
+
+#ifdef CHECK
+  if (!list_SortedInOrder(Result, Test)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In list_Sort: list_MergeSort did not sort properly.");
+    misc_FinishErrorReport();
+  }
+  if (list_Length(Result) != originallength) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In list_Sort: list_MergeSort lost elements. ");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  return Result;
+}
+
+
+/* Help Variable used to store a pointer to the numbering function to use
+   in element comparisons.
+*/
+static NAT (*NumberFunction)(POINTER) = NULL;
+
+static __inline__ BOOL list_PointerNumberedLower(POINTER A, POINTER B) 
+{
+  return (BOOL) (NumberFunction(A) < NumberFunction(B));
+}
+
+static __inline__ BOOL list_PointerNumberedLowerOrEqual(POINTER A, POINTER B) 
+{
+  return (BOOL) (NumberFunction(A) <= NumberFunction(B));
+}
+
+static __inline__ BOOL list_PointerNumberedGreater(POINTER A, POINTER B) 
+{
+  return (BOOL) (NumberFunction(A) > NumberFunction(B));
+}
+
+LIST list_NumberSort(LIST List, NAT (*Number)(POINTER))
+/**************************************************************
+  INPUT:   A list and function mapping elements to numbers.
+  RETURNS: The same list where the elements are sorted with
+           respect to < and the Number function.
+  EFFECT:  The function needs time O((n log n) * f), where <n> 
+           is the length of the list and <f> is the time for a 
+	   call of the <Number> function.
+  CAUTION: Destructive.
+***************************************************************/
+{
+  /* Use number function as temporary variable. It is used as 
+     an implicit parameter in list_PointerLower.
+     We can't make it an explicit parameter, because of the
+     prototype of list_Sort.
+  */
+
+  NumberFunction = Number;
+
+  return list_Sort(List, list_PointerNumberedLower);
+
+}
+
+
+LIST list_GreaterNumberSort(LIST List, NAT (*Number)(POINTER))
+/**************************************************************
+  INPUT:   A list and function mapping elements to numbers.
+  RETURNS: The same list where the elements are sorted with 
+           respect to > and the Number function.
+  EFFECT:  The function needs time O((n log n) * f), where <n> 
+           is the length of the list and <f> is the time for a 
+	   call of the <Number> function.
+  CAUTION: Destructive.
+***************************************************************/
+{
+  /* Use number function as temporary variable. It is used as 
+     an implicit parameter in list_PointerLower.
+     We can't make it an explicit parameter, because of the
+     prototype of list_Sort.
+  */
+
+  NumberFunction = Number;
+
+  return list_Sort(List, list_PointerNumberedGreater);
+}
+
+
+LIST list_NNumberMerge(LIST List1, LIST List2, NAT (*Number)(POINTER))
+/**************************************************************
+  INPUT:   Two sorted lists and function mapping elements to
+           numbers.
+  RETURNS: The merge of the lists where the elements are sorted
+           with respect to < and the Number function.
+  CAUTION: Destructive on both lists.
+***************************************************************/
+{
+  NumberFunction = Number;
+
+  return list_Merge(List1, List2, list_PointerNumberedLowerOrEqual);
+}
+      
+
+POINTER list_DequeueNext(LIST List)
+/**************************************************************
+  INPUT:   A list
+  RETURNS: A pointer to a dequeued element.
+  SUMMARY: We dequeue the element pointed to by list_Cdr(List).
+           The function needs time O(1).
+***************************************************************/
+{
+  POINTER Pointer;
+  LIST    Memo;
+
+  if (list_Empty(List))
+    return NULL;
+
+  Memo = list_Cdr(List);
+  if (list_Empty(Memo))
+    return NULL;
+      
+  Pointer = list_Car(Memo);
+  list_Rplacd(List, Memo->cdr);
+  list_Free(Memo);
+  return Pointer;
+}
+
+
+POINTER list_NthElement(LIST List, NAT Number)
+/**************************************************************
+  INPUT:   A List and a natural number.
+  RETURNS: The <Number>th element of the list, NULL otherwise.
+  EFFECT:  The function needs time O(Number).
+***************************************************************/
+{
+  while (!list_Empty(List) && --Number > 0)
+    List = list_Cdr(List);
+  
+  if (list_Empty(List))
+    return NULL;
+  else
+    return list_Car(List);
+}
+
+
+void list_DeleteWithElement(LIST List, void (*ElementDelete)(POINTER))
+/**************************************************************
+  INPUT:   A list and a delete function for the elements.
+  RETURNS: Nothing.
+  EFFECT:  The list and all its elements are deleted.
+           The function needs time O(n*d), where <n> is the length
+	   of the list and <d> is the time for the delete function.
+***************************************************************/
+{
+  LIST Scan;
+
+  while (!list_Empty(List)) {
+    Scan = list_Cdr(List);
+    ElementDelete(list_Car(List));
+    list_Free(List);
+    List = Scan;
+  }
+}
+
+
+NAT list_DeleteWithElementCount(LIST List, void (*ElementDelete)(POINTER))
+/**************************************************************
+  INPUT:   A List and a delete function for the elements.
+  RETURNS: The number of deleted elements.
+  EFFECT:  The List and all its elements are deleted.
+           The function needs time O(n*d), where <n> is the length
+	   of the list and <d> is the time for the delete function.
+***************************************************************/
+{
+  int  Result;
+  LIST Scan;
+
+  Result = 0;
+
+  while (!list_Empty(List)) {
+    Scan = list_Cdr(List);
+    ElementDelete(list_Car(List));
+    list_Free(List);
+    List = Scan;
+    Result++;
+  }
+
+  return Result;
+}
+
+
+LIST list_DeleteElement(LIST List, POINTER Element, BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+  INPUT:   A list, an element pointer, an equality test for 
+           elements
+  RETURNS: The list where Element is deleted from List with 
+           respect to Test.
+  EFFECTS: If List contains Element with respect to EqualityTest,
+           Element is deleted from List
+  CAUTION: Destructive. Be careful, the first element of a
+           list cannot be changed destructively by call by
+	   reference.
+***************************************************************/
+{
+  LIST   Scan1,Scan2;
+
+  while (!list_Empty(List) && Test(Element, list_Car(List))) {
+    Scan1 = list_Cdr(List);
+    list_Free(List);
+    List = Scan1;
+  }
+
+  if (list_Empty(List))
+    return list_Nil();
+  
+  Scan2 = List;
+  Scan1 = list_Cdr(List);
+
+  while (!list_Empty(Scan1)) {
+    if (Test(Element, list_Car(Scan1))) {
+      list_Rplacd(Scan2, list_Cdr(Scan1));
+      list_Free(Scan1);
+      Scan1 = list_Cdr(Scan2);
+    }
+    else {
+      Scan2 = Scan1;
+      Scan1 = list_Cdr(Scan1);
+    }
+  }
+  return List;
+}
+
+
+LIST list_DeleteElementIf(LIST List, BOOL (*Test)(POINTER))
+/**************************************************************
+  INPUT:   A list and a test for elements.
+  RETURNS: The list where an element is deleted if <Test> on it
+           succeeds.
+  CAUTION: Destructive. Be careful, the first element of a list
+           cannot be changed destructively by call by
+	   reference.
+***************************************************************/
+{
+  LIST   Scan1,Scan2;
+
+  while (!list_Empty(List) && Test(list_Car(List))) {
+    Scan1 = list_Cdr(List);
+    list_Free(List);
+    List = Scan1;
+  }
+
+  if (list_Empty(List)) 
+    return list_Nil();
+  
+  Scan2 = List;
+  Scan1 = list_Cdr(List);
+
+  while (!list_Empty(Scan1)) {
+    if (Test(list_Car(Scan1))) {
+      list_Rplacd(Scan2, list_Cdr(Scan1));
+      list_Free(Scan1);
+      Scan1 = list_Cdr(Scan2);
+    }
+    else {
+      Scan2 = Scan1;
+      Scan1 = list_Cdr(Scan1);
+    }
+  }
+  return List;
+}
+
+
+LIST list_DeleteElementIfFree(LIST List, BOOL (*Test)(POINTER),
+			      void (*Delete)(POINTER))
+/**************************************************************
+  INPUT:   A list, a test for elements and a delete function
+           for elements.
+  RETURNS: The list where an element is deleted if <Test> on it
+           succeeds.
+           The element is deleted with <Delete>.
+  CAUTION: Destructive. Be careful, the first element of a list
+           cannot be changed destructively by call by reference.
+***************************************************************/
+{
+  LIST   Scan1,Scan2;
+
+  while (!list_Empty(List) && Test(list_Car(List))) {
+    Scan1 = list_Cdr(List);
+    Delete(list_Car(List));
+    list_Free(List);
+    List = Scan1;
+  }
+
+  if (list_Empty(List))
+    return list_Nil();
+  
+  Scan2 = List;
+  Scan1 = list_Cdr(List);
+
+  while (!list_Empty(Scan1)) {
+    if (Test(list_Car(Scan1))) {
+      Delete(list_Car(Scan1));
+      list_Rplacd(Scan2, list_Cdr(Scan1));
+      list_Free(Scan1);
+      Scan1 = list_Cdr(Scan2);
+    }
+    else {
+      Scan2 = Scan1;
+      Scan1 = list_Cdr(Scan1);
+    }
+  }
+  return List;
+}
+
+
+
+LIST list_DeleteElementFree(LIST List, POINTER Element,
+			    BOOL (*Test)(POINTER, POINTER),
+			    void (*Free)(POINTER))
+/**************************************************************
+  INPUT:   A list, an element pointer, an equality test for
+           elements and a free function for elements.
+  RETURNS: The list where Element is deleted from List with
+           respect to Test.
+  EFFECTS: If the list contains <Element> with respect to  <Test>,
+           <Element> is deleted from the list and freed.
+  CAUTION: Destructive. Be careful, the first element of a list
+           cannot be changed destructively by call by reference.
+***************************************************************/
+{
+  LIST   Scan1,Scan2;
+
+  while (!list_Empty(List) && Test(Element, list_Car(List))) {
+    Scan1 = list_Cdr(List);
+    Free(list_Car(List));
+    list_Free(List);
+    List = Scan1;
+  }
+
+  if (list_Empty(List))
+    return list_Nil();
+  
+  Scan2 = List;
+  Scan1 = list_Cdr(List);
+
+  while (!list_Empty(Scan1)) {
+    if (Test(Element, list_Car(Scan1))) {
+      list_Rplacd(Scan2, list_Cdr(Scan1));
+      Free(list_Car(Scan1));
+      list_Free(Scan1);
+      Scan1 = list_Cdr(Scan2);
+    }
+    else {
+      Scan2 = Scan1;
+      Scan1 = list_Cdr(Scan1);
+    }
+  }
+  return List;
+}
+
+
+LIST list_DeleteOneElement(LIST List, POINTER Element, BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+  INPUT:   A list, an element pointer and an equality test for
+           elements.
+  RETURNS: The list where at most one element was deleted from
+           <List> if the Test between <Element> and the element
+	   succeeds.
+  EFFECT:  The function needs time O(n*t) in the worst case, and
+           time O(t) in the best case, where <n> is the length of
+	   the list and t is the time for a call of the test function.
+  CAUTION: Destructive. Be careful, the first element of a list
+           cannot be changed destructively by call by
+	   reference.
+	   The memory of the deleted element is not freed.
+***************************************************************/
+{
+  LIST scan1, scan2;
+
+  if (list_Empty(List))
+    return List;
+  else {
+    if (Test(Element, list_Car(List)))
+      return list_Pop(List);
+  }
+  
+  for (scan2 = List, scan1 = list_Cdr(List); !list_Empty(scan1);
+       scan2 = scan1, scan1 = list_Cdr(scan1)) {
+    if (Test(Element, list_Car(scan1))) {
+      list_Rplacd(scan2, list_Cdr(scan1));
+      list_Free(scan1);
+      scan1 = list_Cdr(scan2);
+      return List;
+    }
+  }
+  return List;
+}
+
+
+LIST list_PointerDeleteElement(LIST List, POINTER Element)
+/**************************************************************
+  INPUT:   A list and an element pointer
+  RETURNS: The list where Element is deleted from List with respect to
+           pointer equality.
+  EFFECTS: If <List> contains <Element> with respect to pointer equality,
+           <Element> is deleted from <List>.
+	   This function needs time O(n), where <n> is the length of the list.
+  CAUTION: Destructive. Be careful, the first element of a list cannot
+           be changed destructively by call by reference.
+***************************************************************/
+{
+  LIST   Scan1,Scan2;
+
+  while (!list_Empty(List) && Element == list_Car(List)) {
+    Scan1 = list_Cdr(List);
+    list_Free(List);
+    List = Scan1;
+  }
+
+  if (list_Empty(List))
+    return list_Nil();
+  
+  Scan2 = List;
+  Scan1 = list_Cdr(List);
+
+  while (!list_Empty(Scan1)) {
+    if (Element == list_Car(Scan1)) {
+      list_Rplacd(Scan2, list_Cdr(Scan1));
+      list_Free(Scan1);
+      Scan1 = list_Cdr(Scan2);
+    }
+    else {
+      Scan2 = Scan1;
+      Scan1 = list_Cdr(Scan1);
+    }
+  }
+  return List;
+}
+
+LIST list_PointerDeleteElementFree(LIST List, POINTER Element,
+				   void (*Free)(POINTER))
+/**************************************************************
+  INPUT:   A list, an element pointer and a free function for
+           elements.
+  RETURNS: The list where Element is deleted from List with
+           respect to pointer equality and freed.
+  EFFECTS: If List contains Element with respect to pointer
+           equality, Element is deleted from List
+  CAUTION: Destructive. Be careful, the first element of a list
+           cannot be changed destructively by call by 
+	   reference.
+***************************************************************/
+{
+  LIST   Scan1,Scan2;
+  
+  while (!list_Empty(List) && Element == list_Car(List)) {
+    Scan1 = list_Cdr(List);
+    Free(list_Car(List));
+    list_Free(List);
+    List = Scan1;
+  }
+
+  if (list_Empty(List))
+    return list_Nil();
+  
+  Scan2 = List;
+  Scan1 = list_Cdr(List);
+
+  while (!list_Empty(Scan1)) {
+    if (Element == list_Car(Scan1)) {
+      list_Rplacd(Scan2, list_Cdr(Scan1));
+      Free(list_Car(Scan1));
+      list_Free(Scan1);
+      Scan1 = list_Cdr(Scan2);
+    }
+    else {
+      Scan2 = Scan1;
+      Scan1 = list_Cdr(Scan1);
+    }
+  }
+  return List;
+}
+ 
+
+LIST list_PointerDeleteOneElement(LIST List, POINTER Element)
+/**************************************************************
+  INPUT:   A list and an element pointer.
+  RETURNS: The list where one occurrence of Element is deleted from List 
+           with respect to pointer equality.
+  EFFECTS: If List contains Element with respect to pointer equality,
+           Element is deleted from List.
+  CAUTION: Destructive. Be careful, the first element of a list cannot
+           be changed destructively by call by reference.
+***************************************************************/
+{
+  LIST   Scan1,Scan2;
+
+  if (list_Empty(List))
+    return List;
+  else {
+    if (Element == list_Car(List))
+      return list_Pop(List);
+  }
+  
+  Scan2 = List;
+  Scan1 = list_Cdr(List);
+
+  while (!list_Empty(Scan1)) {
+    if (Element == list_Car(Scan1)) {
+      list_Rplacd(Scan2, list_Cdr(Scan1));
+      list_Free(Scan1);
+      Scan1 = list_Cdr(Scan2);
+      return List;
+    }
+    else {
+      Scan2 = Scan1;
+      Scan1 = list_Cdr(Scan1);
+    }
+  }
+  return List;     
+}
+
+
+BOOL list_DeleteFromList(LIST* List, POINTER Element)
+/**************************************************************
+  INPUT:   A list and an element pointer
+  RETURNS: TRUE, if Element was deleted; FALSE, otherwise.
+  EFFECTS: If List contains Element with respect to pointer equality,
+           all occurrences of Element are deleted from List.
+  CAUTION: Destructive. Be careful, the first element of a list cannot
+           be changed destructively by call by reference.
+***************************************************************/
+{
+  BOOL Found;
+  LIST Scan1;
+
+  Found = FALSE;
+
+  while (list_Exist(*List) && Element == list_Car(*List)) {
+    Scan1 = list_Cdr(*List);
+    list_Free(*List);
+    *List = Scan1;
+    Found = TRUE;
+  }
+
+  if (list_Exist(*List)) {
+    LIST Scan2;
+
+    Scan2 = *List;
+    Scan1 = list_Cdr(*List);
+
+    while (list_Exist(Scan1)) {
+      if (Element == list_Car(Scan1)) {
+	list_Rplacd(Scan2, list_Cdr(Scan1));
+	list_Free(Scan1);
+	Scan1 = list_Cdr(Scan2);
+	Found = TRUE;
+      } else {
+	Scan2 = Scan1;
+	Scan1 = list_Cdr(Scan1);
+      }
+    }
+  }
+
+  return Found;
+}
+
+
+BOOL list_DeleteOneFromList(LIST* List, POINTER Element)
+/**************************************************************
+  INPUT:   A list and an element pointer
+  RETURNS: TRUE, if <Element> was deleted; FALSE, otherwise.
+  EFFECTS: If <List> contains <Element> with respect to pointer equality,
+           the first occurrence of <Element> is deleted from <List>.
+  CAUTION: Destructive.
+***************************************************************/
+{
+  if (list_Exist(*List)) {
+    LIST Scan1;
+
+    /* special treatment for the first element */
+    if (Element == list_Car(*List)) {
+      Scan1 = list_Cdr(*List);
+      list_Free(*List);
+      *List = Scan1;
+      return TRUE;
+    } else {
+      LIST Scan2;
+
+      for (Scan2 = *List, Scan1 = list_Cdr(*List); list_Exist(Scan1); ) {
+	if (Element == list_Car(Scan1)) {
+	  list_Rplacd(Scan2, list_Cdr(Scan1));
+	  list_Free(Scan1);
+	  Scan1 = list_Cdr(Scan2);
+	  return TRUE;
+	} else {
+	  Scan2 = Scan1;
+	  Scan1 = list_Cdr(Scan1);
+	}
+      }
+    }
+  }
+  return FALSE;
+}
+
+
+BOOL list_IsSetOfPointers(LIST L)
+/**************************************************************
+  INPUT:   A list.
+  RETURNS: TRUE, if <L> is a set of pointers (without duplicates),
+           FALSE, otherwise.
+  EFFECT:  The function needs n(n-1)/2 comparisons in the worst case,
+           where n is the length of the list. So its time complexity
+	   is O(n^2).
+***************************************************************/
+{
+  for ( ; !list_Empty(L); L = list_Cdr(L)) {
+    if (list_PointerMember(list_Cdr(L), list_Car(L)))
+      return FALSE;
+  }
+  return TRUE;
+}
+
+
+LIST list_DeleteDuplicates(LIST List, BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+  INPUT:   A list, an equality test for elements
+  RETURNS: The list where multiple occurrences are deleted.
+  CAUTION: Destructive.
+***************************************************************/
+{
+  LIST Scan;
+  
+  Scan = List;
+
+  while (!list_Empty(Scan)) {
+    list_Rplacd(Scan,
+		list_DeleteElement(list_Cdr(Scan), list_Car(Scan), Test));
+    Scan = list_Cdr(Scan);
+  }
+  return List;
+}
+
+
+LIST list_DeleteDuplicatesFree(LIST List, BOOL (*Test)(POINTER, POINTER), 
+			       void (*Free)(POINTER))
+/**************************************************************
+  INPUT:   A list, an equality test for elements, and a free
+           function for elements.
+  RETURNS: The list where multiple occurrences are deleted.
+  CAUTION: Destructive and frees all duplicates.
+***************************************************************/
+{
+  LIST Scan;
+  
+  Scan = List;
+
+  while (!list_Empty(Scan)) {
+    list_Rplacd(Scan, list_DeleteElementFree(list_Cdr(Scan), list_Car(Scan), Test, Free));
+    Scan = list_Cdr(Scan);
+  }
+  return List;
+}
+
+
+LIST list_PointerDeleteDuplicates(LIST List)
+/**************************************************************
+  INPUT:   A list
+  RETURNS: The list where multiple occurrences are deleted.
+  CAUTION: Destructive.
+  EFFECT:  The function needs 
+***************************************************************/
+{
+  LIST Scan;
+  
+  Scan = List;
+
+  while (!list_Empty(Scan)) {
+    list_Rplacd(Scan, list_PointerDeleteElement(list_Cdr(Scan),
+						list_Car(Scan)));
+    Scan = list_Cdr(Scan);
+  }
+  return List;
+}
+
+
+LIST list_NPointerUnion(LIST List1, LIST List2)
+/**************************************************************
+  INPUT:   Two lists.
+  RETURNS: Regarding both lists as sets, the union of the sets.
+  CAUTION: Destructive.
+***************************************************************/
+{
+  return list_PointerDeleteDuplicates(list_Nconc(List1,List2));
+}
+
+
+LIST list_NUnion(LIST List1, LIST List2, BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+  INPUT:   Two lists and an equality test for the elements.
+  RETURNS: Regarding both lists as sets, the union of the sets.
+  CAUTION: Destructive.
+***************************************************************/
+{
+  return list_DeleteDuplicates(list_Nconc(List1,List2), Test);
+}
+
+
+LIST list_NListTimes(LIST List1, LIST List2)
+/**************************************************************
+  INPUT:   Two lists of lists.
+  RETURNS: The list of combinations of element lists.
+  CAUTION: Destroys List1 and List2.
+***************************************************************/
+{
+  LIST Result, Scan1, Scan2;
+
+  Result = list_Nil();
+
+  if (!list_Empty(List2)) {
+    for (Scan1=List1; !list_Empty(Scan1); Scan1=list_Cdr(Scan1))
+      for (Scan2=List2; !list_Empty(Scan2); Scan2=list_Cdr(Scan2))
+	Result = list_Cons(list_Append(((LIST)list_Car(Scan1)),
+				       list_Copy((LIST)list_Car(Scan2))),
+			   Result);
+  }
+  list_DeleteWithElement(List1, (void (*)(POINTER))list_Delete);
+  list_DeleteWithElement(List2, (void (*)(POINTER))list_Delete);
+
+  return Result;
+}
+
+
+LIST list_NIntersect(LIST List1, LIST List2, BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+  INPUT:   Two lists and an equality test for the elements.
+  RETURNS: Regarding both lists as sets, the intersection of the sets.
+  CAUTION: Destructive on List1
+***************************************************************/
+{
+  LIST Scan1, Scan2;
+  
+  while (!list_Empty(List1) && !list_Member(List2, list_Car(List1), Test)) {
+    Scan1 = list_Cdr(List1);
+    list_Free(List1);
+    List1 = Scan1;
+  }
+
+  if (list_Empty(List1))
+    return List1;
+
+  Scan1 = List1;
+  Scan2 = list_Cdr(List1);
+
+  while (!list_Empty(Scan2)) {
+    if (list_Member(List2, list_Car(Scan2), Test)) {
+      Scan2 = list_Cdr(Scan2);
+      Scan1 = list_Cdr(Scan1);
+    }
+    else {
+      list_Rplacd(Scan1, list_Cdr(Scan2));
+      list_Free(Scan2);
+      Scan2 = list_Cdr(Scan1);
+    }
+  }
+  return List1;
+}
+
+
+LIST list_NPointerIntersect(LIST List1, LIST List2)
+/**************************************************************
+  INPUT:   Two lists.
+  RETURNS: Regarding both lists as sets, the intersection of the sets.
+  CAUTION: Destructive on List1
+***************************************************************/
+{
+  LIST Scan1, Scan2;
+  
+  while (!list_Empty(List1) && !list_PointerMember(List2, list_Car(List1))) {
+    Scan1 = list_Cdr(List1);
+    list_Free(List1);
+    List1 = Scan1;
+  }
+
+  if (list_Empty(List1))
+    return List1;
+
+  Scan1 = List1;
+  Scan2 = list_Cdr(List1);
+
+  while (!list_Empty(Scan2)) {
+    if (list_PointerMember(List2, list_Car(Scan2))) {
+      Scan2 = list_Cdr(Scan2);
+      Scan1 = list_Cdr(Scan1);
+    }
+    else {
+      list_Rplacd(Scan1, list_Cdr(Scan2));
+      list_Free(Scan2);
+      Scan2 = list_Cdr(Scan1);
+    }
+  }
+  return List1;
+}
+
+
+void list_NInsert(LIST List1, LIST List2)
+/**************************************************************
+  INPUT:   Two lists where <List1> must not be empty.
+  EFFECT:  <List2> is destructively concatenated after
+           the first element of <List1>.
+  RETURNS: void.
+  CAUTION: Destructive on List1 and List2.
+***************************************************************/
+{
+  LIST Help;
+
+#ifdef CHECK
+  if (list_Empty(List1)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In list_NInsert: Empty list argument.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Help = list_Cdr(List1);
+  list_Rplacd(List1,List2);
+  List2 = List1;
+
+  while (!list_Empty(list_Cdr(List2)))
+    List2 = list_Cdr(List2);
+
+  list_Rplacd(List2,Help);
+}
+
+      
+BOOL list_HasIntersection(LIST List1, LIST List2)
+/**************************************************************
+  INPUT:   Two lists .
+  RETURNS: TRUE iff List1 and List2 have a common element.
+  EFFECT:  The function needs time O(n*m), where n and m are the
+           lengths of the lists.
+***************************************************************/
+{ 
+  LIST Scan;
+
+  if (!list_Empty(List2)) {
+    for (Scan=List1; !list_Empty(Scan); Scan=list_Cdr(Scan))
+      if (list_PointerMember(List2, list_Car(Scan)))
+	return TRUE;
+  }
+  return FALSE;
+}
+
+
+LIST list_NPointerDifference(LIST List1, LIST List2)
+/**************************************************************
+  INPUT:   Two lists.
+  RETURNS: The list List1-List2.
+  CAUTION: Destructive on List1.
+***************************************************************/
+{ 
+  LIST Scan;
+
+  if (!list_Empty(List1)) {
+    for (Scan=List2; !list_Empty(Scan); Scan=list_Cdr(Scan))
+      List1 = list_PointerDeleteElement(List1, list_Car(Scan));
+  }
+  return List1;
+}
+
+
+LIST list_NDifference(LIST List1, LIST List2, BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+  INPUT:   Two lists and an equality test for elements.
+  RETURNS: The list List1-List2 wrt. <Test>.
+  CAUTION: Destructive on List1.
+***************************************************************/
+{ 
+  LIST Scan;
+  
+  if (!list_Empty(List1)) {
+    for (Scan=List2; !list_Empty(Scan); Scan=list_Cdr(Scan))
+      List1 = list_DeleteElement(List1, list_Car(Scan), Test);
+  }
+  return List1;
+}
+
+
+LIST list_NMultisetDifference(LIST List1, LIST List2, BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+  INPUT:   Two lists representing multisets and an equality
+           test for elements.
+  RETURNS: The multiset difference List1-List2 wrt. <Test>.
+  CAUTION: Destructive on List1. The memory of deleted
+           elements is not freed.
+***************************************************************/
+{
+  LIST scan;
+  /* Delete equal arguments */
+  if (!list_Empty(List1)) {
+    for (scan = List2; !list_Empty(scan); scan = list_Cdr(scan))
+      /* Delete at most one element from List1 equal to */
+      /* the actual element of List2. */
+      List1 = list_DeleteOneElement(List1, list_Car(scan), Test);
+  }
+  return List1;
+}
+
+    
+BOOL list_PointerReplaceMember(LIST List, POINTER Old, POINTER New)
+/**************************************************************
+  INPUT:   A list, a pointer to an old element, a pointer to a new element
+  RETURNS: TRUE iff <Old> was replaced.
+  EFFECT:  The first occurrence of <Old> in the list is replaced by <New>.
+***************************************************************/
+{
+  while (!list_Empty(List)) {
+    if (Old == list_Car(List)) {
+      list_Rplaca(List, New);
+      return TRUE;
+    }
+    List = list_Cdr(List);
+  }
+  return FALSE;
+}   
+
+  
+void list_DeleteAssocListWithValues(LIST List, void (*ValueDelete)(POINTER))
+/**************************************************************
+  INPUT:   An association list and a delete function for the values.
+  RETURNS: void.
+  EFFECT:  The assoc list and its values are deleted.
+***************************************************************/
+{
+  LIST Scan;
+
+  for (Scan=List;!list_Empty(Scan);Scan = list_Cdr(Scan)) {
+    ValueDelete(list_PairSecond(list_Car(Scan)));
+    list_PairFree(list_Car(Scan));
+  }
+
+  list_Delete(List);
+}
+
+
+POINTER list_AssocListValue(LIST List, POINTER Key)
+/**************************************************************
+  INPUT:   An association list and a key.
+  RETURNS: The value for <key> in the list. If <key> is not
+           contained, NULL.
+***************************************************************/
+{
+  LIST Scan;
+
+  for (Scan=List;!list_Empty(Scan);Scan = list_Cdr(Scan))
+    if (Key == list_PairFirst(list_Car(Scan)))
+      return list_PairSecond(list_Car(Scan));
+
+  return NULL;
+}
+
+
+LIST list_AssocListPair(LIST List, POINTER Key)
+/**************************************************************
+  INPUT:   An association list and a key.
+  RETURNS: The  (<key>.<value) in the list. If <key> is not
+           contained, the NULL pair.
+***************************************************************/
+{
+  LIST Scan;
+
+  for (Scan=List;!list_Empty(Scan);Scan = list_Cdr(Scan))
+    if (Key == list_PairFirst(list_Car(Scan)))
+      return list_Car(Scan);
+
+  return list_PairNull();
+}
+
+
+LIST list_MultisetDistribution(LIST Multiset) 
+/**************************************************************
+  INPUT:   A list representing a multiset.
+  RETURNS: The associative list of pairs (<element>.<occurrences>) 
+           representing the distribution of elements in the list.
+	   If the input multiset is empty, the NULL pair.
+***************************************************************/
+{
+  LIST Distribution;
+  LIST Scan;
+
+  Distribution = list_PairNull();
+
+  for (Scan = Multiset; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    LIST    Count;
+    POINTER Element;
+    int     Occurences;
+
+    Element = list_Car(Scan);
+    Count   = list_AssocListPair(Distribution, Element);
+
+    if (Count != list_PairNull()) {
+      Occurences = (int) list_PairSecond(Count);
+      list_PairRplacSecond(Count, (POINTER) (Occurences + 1));
+    }
+    else {
+      Distribution = list_AssocCons(Distribution, Element, (POINTER) 1);
+    }
+  }
+
+  return Distribution;
+}
+
+
+int list_CompareElementDistribution(LIST LeftPair, LIST RightPair) 
+/**************************************************************
+  INPUT:   Two lists, representing single element frequency 
+           counts.
+  RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+  EFFECT:  Compares two element frequencies.
+***************************************************************/
+{
+  if ((int) list_PairSecond(LeftPair) < (int) list_PairSecond(RightPair)) {
+    return -1;
+  }
+  else if ((int) list_PairSecond(LeftPair) > (int) list_PairSecond(RightPair)) {
+    return 1;
+  }
+
+  return 0;
+}
+
+
+BOOL list_CompareElementDistributionLEQ(LIST LeftPair, LIST RightPair) {
+/**************************************************************
+  INPUT:   Two lists, representing single element frequency 
+           counts.
+  RETURNS: TRUE if left <= right, FALSE otherwise.
+  EFFECT:  Compares two element frequencies.
+***************************************************************/
+  return (list_CompareElementDistribution(LeftPair, RightPair) <= 0);
+}
+
+
+static int list_CompareDistributions(LIST Left, LIST Right) 
+/**************************************************************
+  INPUT:   Two lists, representing element distributions.
+  RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+  EFFECT:  Compares the two distributions by comparing the 
+           element frequencies from left to right.
+  CAUTION: Expects the distributions to be sorted.
+***************************************************************/
+{
+  LIST scan, scan2;
+  int result;
+
+  result = 0;
+
+  scan  = Left;
+  scan2 = Right;
+
+  /* Compare distributions. */
+
+  while ( !(list_Empty(scan) || list_Empty(scan2))) {
+    result = list_CompareElementDistribution(list_Car(scan), list_Car(scan2));
+    if (result != 0) {
+      break;
+    }
+    
+    scan  = list_Cdr(scan);
+    scan2 = list_Cdr(scan2);
+  }
+
+  /* If the result is 0, and a distribution still
+     has elements left, it is declared to be greater.
+  */
+  if (result == 0) {
+    if (list_Empty(scan) && !list_Empty(scan2))
+      result = -1;
+    else if (!list_Empty(scan) && list_Empty(scan2))
+      result = 1;
+  }
+
+  return result;
+}
+
+
+int list_CompareMultisetsByElementDistribution(LIST Left, LIST Right) 
+/**************************************************************
+  INPUT:   Two lists, representing multisets.
+  RETURNS: 1 if left > right, -1 if left < right, 0 otherwise.
+  EFFECT:  Compares two multisets by counting their element 
+           frequencies, sorting them, and comparing the 
+	   resulting multisets over natural numbers.
+***************************************************************/
+{
+  LIST lmsd, rmsd; /* multiset distributions. */
+  int result;
+
+  /* Convert multiset of elements into a
+     multiset of pairs (element, occurrences).
+  */
+
+  lmsd = list_MultisetDistribution(Left);
+  rmsd = list_MultisetDistribution(Right);
+
+  /* Sort multiset distributions in order 
+     to make them comparable. 
+   */
+
+  lmsd = list_Sort(lmsd, (BOOL (*) (POINTER, POINTER)) list_CompareElementDistributionLEQ);
+  rmsd = list_Sort(rmsd, (BOOL (*) (POINTER, POINTER)) list_CompareElementDistributionLEQ);
+
+  result = list_CompareDistributions(lmsd, rmsd);
+
+  list_DeleteDistribution(lmsd);
+  list_DeleteDistribution(rmsd);
+
+  return result;
+}
+
+
+NAT list_Length(LIST List)
+/**************************************************************
+  INPUT:   A List.
+  RETURNS: The number of elements..
+  EFFECT:  The function needs time O(n), where <n> is the length
+           of the list.
+***************************************************************/
+{
+  NAT Result;
+
+  Result = 0;
+
+  while (!list_Empty(List)) {
+    Result++;
+    List = list_Cdr(List);
+  }
+
+  return Result;
+}
+
+
+NAT list_Bytes(LIST List)
+/**************************************************************
+  INPUT:   A List.
+  RETURNS: The number of Bytes occupied by the list structure of <List>
+  EFFECT:  the function needs time O(n), where <n> is the length
+           of the list.
+***************************************************************/
+{
+  return (list_Length(List)*sizeof(LIST_NODE));
+}
diff --git a/test/spass/list.h b/test/spass/list.h
new file mode 100644
index 0000000000000000000000000000000000000000..fa390a3476151b24836155ac6f814b059246251e
--- /dev/null
+++ b/test/spass/list.h
@@ -0,0 +1,433 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                     LISTS                              * */
+/* *                                                        * */
+/* *  $Module:   LIST                                       * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000            * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _LIST_
+#define _LIST_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "memory.h"
+#include "misc.h"
+
+/**************************************************************/
+/* Structures                                                 */
+/**************************************************************/
+
+typedef struct LIST_HELP {
+  struct LIST_HELP *cdr;
+  POINTER           car;
+} LIST_NODE;
+
+typedef LIST_NODE *LIST;
+
+/**************************************************************/
+/* Macros                                                     */
+/**************************************************************/
+
+static __inline__ void list_Free(LIST L)
+{
+  memory_Free(L, sizeof(LIST_NODE));
+}
+
+static __inline__ LIST list_Nil(void)
+{
+  return NULL;
+}
+
+static __inline__ BOOL list_Empty(LIST L)
+{
+  return L == NULL;
+}
+
+static __inline__ BOOL list_Exist(LIST L)
+{
+  return L != NULL;
+}
+
+static __inline__ POINTER list_Car(LIST L)
+{
+  return L->car;
+}
+
+static __inline__ POINTER list_NCar(LIST *L)
+{
+  POINTER Result;
+  LIST    Help;
+
+  Result = (*L)->car;
+  Help   = (*L)->cdr;
+  list_Free(*L);
+  *L     = Help;
+  return Result;
+}
+
+static __inline__ LIST list_Cdr(LIST L)
+{
+  return L->cdr;
+}
+
+static __inline__ POINTER list_First(LIST L)
+{
+  return list_Car(L);
+}
+
+static __inline__ POINTER list_Second(LIST L)
+{
+  return list_Car(list_Cdr(L));
+}
+
+static __inline__ POINTER list_Third(LIST L)
+{
+  return list_Car(list_Cdr(list_Cdr(L)));
+}
+
+static __inline__ POINTER list_Fourth(LIST L) 
+{
+  return(list_Third(list_Cdr(L)));
+}
+
+static __inline__ POINTER list_Fifth(LIST L) 
+{
+  return(list_Fourth(list_Cdr(L)));
+}
+
+static __inline__ void list_Rplacd(LIST L1, LIST L2)
+{
+  L1->cdr = L2;
+}
+
+static __inline__ void list_Rplaca(LIST L, POINTER P)
+{
+  L->car = P;
+}
+
+static __inline__ void list_RplacSecond(LIST L, POINTER P)
+{
+  list_Rplaca(list_Cdr(L), P);
+}
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+LIST    list_Copy(const LIST);
+LIST    list_CopyWithElement(const LIST, POINTER (*)(POINTER));
+void    list_InsertNext(LIST, POINTER);
+
+void    list_NMapCar(LIST, POINTER (*)(POINTER));
+void    list_Apply(void (*)(POINTER), LIST);
+
+LIST    list_Reverse(const LIST);
+LIST    list_NReverse(LIST);
+
+void    list_Split(LIST, LIST *, LIST *); 
+LIST    list_PointerSort(LIST);
+LIST    list_Merge(LIST, LIST, BOOL (*)(POINTER, POINTER));
+LIST    list_MergeSort(LIST, BOOL (*)(POINTER, POINTER));
+LIST    list_InsertionSort(LIST, BOOL (*)(POINTER, POINTER));
+LIST    list_Sort(LIST, BOOL (*)(POINTER, POINTER));
+BOOL    list_SortedInOrder(LIST, BOOL (*)(POINTER, POINTER));
+LIST    list_NumberSort(LIST , NAT (*)(POINTER));
+LIST    list_GreaterNumberSort(LIST , NAT (*)(POINTER));
+LIST    list_NNumberMerge(LIST , LIST, NAT (*)(POINTER));
+
+POINTER list_DequeueNext(LIST);
+POINTER list_NthElement(LIST, NAT);
+void    list_DeleteWithElement(LIST, void (*)(POINTER));
+NAT     list_DeleteWithElementCount(LIST, void (*)(POINTER));
+LIST    list_DeleteElement(LIST, POINTER, BOOL (*)(POINTER, POINTER));
+LIST    list_DeleteElementIf(LIST, BOOL (*)(POINTER));
+LIST    list_DeleteElementIfFree(LIST, BOOL (*)(POINTER), void (*)(POINTER));
+LIST    list_DeleteElementFree(LIST, POINTER, BOOL (*)(POINTER, POINTER), void (*)(POINTER));
+LIST    list_DeleteOneElement(LIST, POINTER, BOOL (*)(POINTER, POINTER));
+LIST    list_PointerDeleteElement(LIST, POINTER);
+LIST    list_PointerDeleteElementFree(LIST, POINTER, void (*)(POINTER));
+LIST    list_PointerDeleteOneElement(LIST, POINTER);
+BOOL    list_DeleteFromList(LIST*, POINTER);
+BOOL    list_DeleteOneFromList(LIST*, POINTER);
+LIST    list_DeleteDuplicates(LIST, BOOL (*)(POINTER, POINTER));
+LIST    list_DeleteDuplicatesFree(LIST, BOOL (*)(POINTER, POINTER), void (*)(POINTER));
+LIST    list_PointerDeleteDuplicates(LIST);
+
+BOOL    list_IsSetOfPointers(LIST);
+LIST    list_NPointerUnion(LIST, LIST);
+LIST    list_NUnion(LIST, LIST, BOOL (*)(POINTER, POINTER));
+LIST    list_NListTimes(LIST, LIST);
+LIST    list_NIntersect(LIST, LIST, BOOL (*)(POINTER, POINTER));
+void    list_NInsert(LIST, LIST);
+LIST    list_NPointerIntersect(LIST, LIST);
+BOOL    list_HasIntersection(LIST, LIST);
+LIST    list_NPointerDifference(LIST, LIST);
+LIST    list_NDifference(LIST, LIST, BOOL (*)(POINTER, POINTER));
+LIST    list_NMultisetDifference(LIST, LIST, BOOL (*)(POINTER, POINTER));
+BOOL    list_PointerReplaceMember(LIST, POINTER, POINTER);
+
+void    list_DeleteAssocListWithValues(LIST, void (*)(POINTER));
+POINTER list_AssocListValue(LIST, POINTER);
+LIST    list_AssocListPair(LIST, POINTER);
+
+LIST    list_MultisetDistribution(LIST);
+int     list_CompareMultisetsByElementDistribution(LIST, LIST);
+
+NAT     list_Length(LIST);
+NAT     list_Bytes(LIST);
+
+/**************************************************************/
+/* Functional Inline Functions                                */
+/**************************************************************/
+
+static __inline__ LIST list_Cons(POINTER Ptr, const LIST List)
+{
+  LIST Cell;
+
+  Cell = (LIST)memory_Malloc(sizeof(LIST_NODE));
+  Cell->car = Ptr;
+  Cell->cdr = List;
+  return Cell;
+}
+
+
+static __inline__ LIST list_Nconc(LIST List1, LIST List2)
+{
+  LIST Result;
+
+  if (list_Empty(List1))
+    return List2;
+
+  if (list_Empty(List2))
+    return List1;
+
+  Result = List1;
+  for (List1 = Result; !list_Empty(list_Cdr(List1)); List1 = list_Cdr(List1))
+    /* empty */;
+  List1->cdr = List2;
+  return Result;
+}
+
+
+static __inline__ LIST list_List(POINTER P)
+{
+  return list_Cons(P,list_Nil());
+}
+
+
+static __inline__ LIST list_Append(LIST List1, LIST List2)
+{
+  LIST Result;
+
+  if (list_Empty(List1))
+    return List2;
+  if (list_Empty(List2))
+    return list_Copy(List1);
+
+  Result = list_Copy(List1);
+  for (List1 = Result; !list_Empty(list_Cdr(List1)); List1 = list_Cdr(List1))
+    /* empty */;
+  List1->cdr = List2;
+  return Result;
+}
+
+
+static __inline__ void list_Delete(LIST L)
+{
+  LIST Current;
+
+  Current = L;
+  while (!list_Empty(Current)) {
+    L = list_Cdr(L);
+    list_Free(Current);
+    Current = L;
+  }
+}
+
+static __inline__ BOOL list_Member(LIST List, POINTER Element,
+				   BOOL (*Test)(POINTER, POINTER))
+/**************************************************************
+  INPUT:   A list and an element pointer and an equality test for two elements.
+  RETURNS: TRUE iff Element is in List with respect to Test
+***************************************************************/
+{
+  while (!list_Empty(List)) {
+    if (Test(Element, list_Car(List)))
+      return TRUE;
+    List = list_Cdr(List);
+  }
+  
+  return FALSE;
+}
+
+
+static __inline__ BOOL list_PointerMember(LIST List, POINTER Element)
+/**************************************************************
+  INPUT:   A list and an element pointer.
+  RETURNS: TRUE iff Element is in List with respect to pointer equality.
+***************************************************************/
+{
+  while (!list_Empty(List)) {
+    if (Element == list_Car(List))
+      return TRUE;
+    List = list_Cdr(List);
+  }
+  
+  return FALSE;
+}
+
+/**************************************************************/
+/* Stack Macros                                               */
+/**************************************************************/
+
+static __inline__ LIST list_StackBottom(void)
+{
+  return list_Nil();
+}
+
+
+static __inline__ BOOL list_StackEmpty(LIST S)
+{
+  return list_Empty(S);
+}
+
+
+static __inline__ LIST list_Push(POINTER I, LIST L)
+{
+  return list_Cons(I, L);
+}
+
+
+static __inline__ POINTER list_Top(LIST L)
+{
+  return list_Car(L);
+}
+
+
+static __inline__ LIST list_Pop(LIST L)
+{
+  LIST Aux = L; 
+
+  L = list_Cdr(L);
+  list_Free(Aux);
+  return L;
+}
+
+
+static __inline__ void list_RplacTop(LIST L, POINTER P)
+{
+  list_Rplaca(L, P);
+}
+
+
+static __inline__ LIST list_StackFree(LIST L)
+{
+  while (!list_StackEmpty(L))
+    L = list_Pop(L);
+  return list_Nil();
+}
+
+
+/**************************************************************/
+/* Pair Macros                                                */
+/**************************************************************/
+
+static __inline__ LIST list_PairNull(void)
+{
+  return list_Nil();
+}
+
+
+static __inline__ LIST list_PairCreate(POINTER P1, POINTER P2)
+{
+  return list_Cons(P1, P2);
+}
+
+
+static __inline__ void list_PairFree(LIST L)
+{
+  list_Free(L);
+}
+
+
+static __inline__ POINTER list_PairFirst(LIST L)
+{
+  return list_Car(L);
+}
+
+
+static __inline__ POINTER list_PairSecond(LIST L)
+{
+  return (POINTER)list_Cdr(L);
+}
+
+static __inline__ void list_PairRplacSecond(LIST L, POINTER P)
+{
+  list_Rplacd(L,P);
+}
+
+static __inline__ void list_DeletePairList(LIST L)
+  /* Delete a list of pairs */
+{
+  list_DeleteWithElement(L, (void (*)(POINTER))list_PairFree);
+}
+
+static __inline__ void list_DeleteDistribution(LIST L)
+{
+  list_DeletePairList(L);
+}
+
+/**************************************************************/
+/* Assoc Lists                                                */
+/**************************************************************/
+
+
+static __inline__ LIST list_AssocCons(LIST L, POINTER Key, POINTER Value)
+{
+  return list_Cons(list_PairCreate(Key, Value), L);
+} 
+
+#endif
diff --git a/test/spass/memory.c b/test/spass/memory.c
new file mode 100644
index 0000000000000000000000000000000000000000..a785515d302e5d686bc0f384e3195805b18b2057
--- /dev/null
+++ b/test/spass/memory.c
@@ -0,0 +1,1595 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *        DYNAMIC MEMORY MANAGEMENT MODULE                * */
+/* *                                                        * */
+/* *  $Module:   MEMORY                                     * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "memory.h"
+
+unsigned int  memory_PAGESIZE;   /* size of a page                            */
+long          memory_MAXMEM;     /* amount of memory available for allocation */
+static int    memory__EOF = EOF; /* internal "End Of Memory" marker           */
+unsigned long memory_NEWBYTES;   /* number of allocated bytes                 */
+unsigned long memory_FREEDBYTES; /* number of freed bytes                     */
+
+const unsigned int memory_ALIGN = sizeof(POINTER); 
+/* Crucial: hardware must support access to words 
+   of size POINTER.
+*/
+
+#ifdef CHECK
+unsigned int memory_LEFTTAG;     /* size of left debug mark                   */
+unsigned int memory_OFFSET;      /* alignment-correct size of left debug mark */
+unsigned int memory_MARKSIZE;    /* total size of debug marks                 */
+
+BOOL         memory_MANAGEMENT_INITIALIZED = FALSE;
+
+#else  /* CHECK not defined */
+unsigned int memory_MARKSIZE = 0;
+unsigned int memory_OFFSET   = 0;
+#endif /* CHECK */
+
+const unsigned int memory_MAGICMALLOC = 1; /* "block allocated" marker */
+const unsigned int memory_MAGICFREE   = 2; /* "block freed" marker     */
+
+/* Internal array of resources for different block sizes */
+/* ... + 1 to support odd values for memory__SHAREDPAGES like 7 */
+static MEMORY_RESOURCE memory_PAGES[memory__DYNMAXSIZE/memory__SHAREDPAGES + 1];
+
+
+/* Resources for all administrated block sizes */
+MEMORY_RESOURCE * memory_ARRAY[memory__DYNMAXSIZE];
+
+/* double linked list for administering blocks of memory
+   whose size is greater or equal to memory__DYNMAXSIZE.
+*/ 
+MEMORY_BIGBLOCKHEADER memory_BIGBLOCKS = NULL;
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  INITIALIZATION                                        * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+#ifdef CHECK
+static BOOL memory_ManagementInitialized(void)
+/**********************************************************
+   INPUT  : None.
+   RETURNS: TRUE if memory management is already initialized,
+            else FALSE.
+   SUMMARY: Checks if memory_Init was called.
+**********************************************************/
+{
+  return memory_MANAGEMENT_INITIALIZED;
+}
+#endif /* CHECK */
+
+void memory_Init(long Maxmem)
+/*************************************************************
+  INPUT  : The maximal amount of memory available in bytes 
+           for the memory module; if Maxmem < 0 the module 
+           allocates as much memory as available from the 
+           system.
+  RETURNS: None.
+  SUMMARY: Initializes the memory management. It has to be 
+           called before you can perform any module operation. 
+           This function automatically increases the default 
+           page size if it is too small for two objects of 
+           size memory__DYNMAXSIZE.
+*************************************************************/
+{
+  int i;
+  int extra;             /* size of internally used space on each page  */
+
+  memory_FREEDBYTES = 0; /* set total number of freed bytes to zero     */
+  memory_NEWBYTES   = 0; /* set total number of allocated bytes to zero */
+
+  /* set the size of a page we allocate from the operating system */
+  memory_PAGESIZE   = memory__DEFAULTPAGESIZE;
+
+#ifdef CHECK
+
+  /* Test if memory management has already been initialized */
+ 
+  if (!memory_ManagementInitialized()) {
+    /* if that is not the case, set check variable to TRUE */
+    memory_MANAGEMENT_INITIALIZED = TRUE;
+  }
+  else {
+    /* otherwise the user is trying initialize it for a 
+       second time, so print an error and exit.
+    */
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n In memory_Init:");
+    misc_UserErrorReport("\n Memory Error.");
+    misc_UserErrorReport(" Trying to initialize memory management");
+    misc_UserErrorReport(" for a second time.\n");
+    misc_FinishUserErrorReport();
+  }
+
+  /* Calculate the size of debug marks */
+  memory_LEFTTAG  = sizeof(MEMORY_INFONODE) + sizeof(unsigned int);
+
+  if ((sizeof(MEMORY_INFONODE) + sizeof(unsigned int)) % memory_ALIGN == 0) {
+    memory_OFFSET   = memory_LEFTTAG;
+  }
+  else {
+    memory_OFFSET   = memory_LEFTTAG + memory_ALIGN 
+      - (memory_LEFTTAG % memory_ALIGN);
+  }
+
+  if ((sizeof(unsigned int) % memory_ALIGN) == 0) {
+    memory_MARKSIZE =  memory_OFFSET + sizeof(unsigned int);
+  }
+  else {
+    memory_MARKSIZE =  memory_OFFSET + sizeof(unsigned int) + memory_ALIGN 
+      - (sizeof(unsigned int) % memory_ALIGN);
+  }
+#endif
+
+  /* Calculate the size of internally used space on each page */
+  /* extra: One pointer for chaining pages, one for EOF (+ marksize) */
+  extra = 2*sizeof(POINTER) + memory_MARKSIZE; 
+
+
+  /* Test whether page size is reasonable with respect 
+     to dynamic allocation threshold
+  */
+  while (memory_PAGESIZE < (2*(memory__DYNMAXSIZE + memory_MARKSIZE) + extra)) {
+    /* Minimum two objects per allocated page */
+    memory_PAGESIZE += memory__DEFAULTPAGESIZE/2;    
+  }
+
+  /* Set amount of memory available to the module for allocation */
+  if (Maxmem <= 0) {
+    /* unlimited (limited only by the operating system) */
+    memory_MAXMEM = memory__UNLIMITED;
+  }
+  else {
+    /* Maxmem bytes */
+    memory_MAXMEM = Maxmem;
+  }
+
+  /* Initialize memory_ARRAY and memory_RESOURCEs */
+  for (i=1; i<memory__DYNMAXSIZE; i++) {
+    MEMORY_RESOURCE *CurrentResource;
+    int             TotalSize;
+
+    /* Map memory_ARRAY[i] to appropriate Resource */
+    memory_ARRAY[i]               = &memory_PAGES[(i-1)/memory__SHAREDPAGES];
+
+    CurrentResource = memory_ARRAY[i];
+
+    CurrentResource->free            = &memory__EOF; /* no blocks freed     */
+    CurrentResource->next            = &memory__EOF; /* no blocks allocated */
+    CurrentResource->end_of_page     = &memory__EOF; /* no (end of) page    */
+    CurrentResource->page            = &memory__EOF; /* no page allocated   */
+
+    /* Size of a properly aligned block of requested size i */
+    CurrentResource->aligned_size    = memory_CalculateRealBlockSize(i);
+
+    /* Total block size including debug marks */
+    CurrentResource->total_size      = memory_MARKSIZE 
+      + CurrentResource->aligned_size;
+
+    TotalSize                        = CurrentResource->total_size;
+
+    /* last block´s offset */
+    CurrentResource->offset          =
+      ((memory_PAGESIZE-extra)/TotalSize)*TotalSize 
+      + sizeof(POINTER) + memory_OFFSET;
+  }
+}
+
+
+void memory_Restrict(long Maxmem)
+/*************************************************************
+  INPUT  : The maximal amount of memory available for further 
+           allocation (in bytes); if Maxmem < 0 future 
+           allocations are unrestricted.
+  RETURNS: None.
+  SUMMARY: Sets the maximal amount of memory available for 
+           future allocations. If the user tries to allocate 
+           more memory, the module displays an error message 
+           and terminates the program by calling the exit() 
+           function.
+*************************************************************/
+{
+  /* Reset the maximum amount of memory available */ 
+  if (Maxmem <= 0) {
+    /* unlimited */
+    memory_MAXMEM = memory__UNLIMITED;
+  }
+  else {
+    /* Maxmem bytes */
+    memory_MAXMEM = Maxmem;
+  }
+}
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  CHECK CODE                                            * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+#ifdef CHECK
+static void memory_CheckIfModuleIsInitialized(const char * Function,
+				       const char * File,
+				       unsigned short int Line)
+/********************************************************
+  INPUT  : The name of the function that requests the
+           check, the name of the file and the line, 
+	   where the requesting function was called, and
+	   the line.
+  RETURNS: None.
+  SUMMARY: Checks if the memory management module has
+           been properly initialized. You need to
+	   initialize the module by calling memory_Init
+	   before you use any functions from the module.
+	   If the check fails, this function prints an
+	   error message and exits the application.
+*********************************************************/
+{
+  if (!memory_ManagementInitialized()) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n In %s:", Function);
+    misc_UserErrorReport("\n Memory Error.");
+    misc_UserErrorReport(" Memory management is not initialized.");
+    misc_UserErrorReport("\n You have to call memory_Init()");
+    misc_UserErrorReport(" before you can use memory management functions.\n");
+    misc_UserErrorReport("\n Error occurred in %s", Function);
+    misc_UserErrorReport(" called from file %s at line %d.\n",
+			 File, Line);
+    misc_FinishUserErrorReport();
+  }
+}
+
+static void memory_CheckIfPointerIsAlreadyFreed(POINTER Pointer,
+					 const char * Function,
+					 const char * File,
+					 unsigned short int Line)
+/********************************************************
+  INPUT  : The pointer to be checked, the name of the
+           function that requests the check, the name of
+	   the file and the line, where the requesting
+	   function was called, and the line.
+  RETURNS: None.
+  SUMMARY: Checks if the pointer has already been freed.
+	   If the check fails, this function prints an
+	   error message and exits the application.
+*********************************************************/
+{
+  if ( memory_GetBlockStatus(Pointer) == memory_MAGICFREE) {
+    MEMORY_INFO  Info;          /* block´s debug information      */
+
+    Info = (MEMORY_INFO) ((char *) Pointer - memory_OFFSET);
+
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n In %s:", Function);
+    misc_UserErrorReport("\n Memory Error.");
+    misc_UserErrorReport(" Pointer %p was allocated in file %s at line %d.",
+			 Pointer, Info->mallocInFile, Info->mallocAtLine);
+    misc_UserErrorReport("\n It has already been freed in file %s at line %d.",
+			 Info->freeInFile, Info->freeAtLine);
+    misc_UserErrorReport("\n Size of memory block is %d bytes.",
+			 memory_GetBlockSize(Pointer));
+    misc_UserErrorReport("\n Error occurred in %s", Function);
+    misc_UserErrorReport(" called from file %s at line %d.\n",
+			 File, Line);
+    misc_FinishUserErrorReport();
+  }
+}
+
+static void memory_CheckPointer(POINTER Pointer, unsigned int Size) 
+/*********************************************************
+  INPUT  : A pointer to a block of memory, and its size.
+  RETURNS: Nothing.
+  SUMMARY: Checks whether a pointer points to a valid
+           block of memory.
+	    
+           This function performs the following tests:
+
+           Is Pointer a NULL pointer?
+
+           Is Size equal to zero?
+
+           Is the Pointer alignment correct?
+	
+           Did someone write over the memory block 
+           boundaries?
+
+           Is Size still correct?
+
+           If Size is greater than memory__DYNMAXSIZE: 
+           Is it properly administrated by the module?
+
+           If the memory block was freed: Did someone 
+           write to it after deallocation?
+*********************************************************/
+{
+
+  MEMORY_INFO Info;
+  unsigned int BlockSize, RealBlockSize, BlockStatus;
+
+  Info = (MEMORY_INFO) ((char *) Pointer - memory_OFFSET);
+
+  RealBlockSize = memory_LookupRealBlockSize(Size);
+
+  if (Pointer == NULL) {
+    /* NULL pointers must not be dereferenced */
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n In memory_CheckPointer:");
+    misc_UserErrorReport("\n Memory Error. Pointer is a NULL pointer.\n");
+    misc_FinishUserErrorReport();
+  }
+
+
+  if (Size == 0) {
+    /* We don´t allocate 0 byte sized blocks */
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n In memory_CheckPointer:");
+    misc_UserErrorReport("\n Memory Error.");
+    misc_UserErrorReport(" Pointer %p points to a block of memory", Pointer);
+    misc_UserErrorReport(" with size 0.\n"); 
+    misc_FinishUserErrorReport();
+  }
+
+  if ((unsigned long)Pointer % (unsigned long)memory_ALIGN){
+    /* we expect all pointers to be correctly aligned */
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n In memory_CheckPointer:");
+    misc_UserErrorReport("\n Memory Error.");
+    misc_UserErrorReport(" Pointer %p is not a legal pointer.\n", Pointer);
+    misc_FinishUserErrorReport();
+  }
+
+  /* BlockStatus and BlockSize are initialized after
+     we can be sure Pointer is properly aligned.
+  */
+
+  BlockStatus   = memory_GetBlockStatus(Pointer);
+  BlockSize     = memory_GetBlockSize(Pointer);
+
+  if (BlockStatus != memory_MAGICMALLOC 
+      && BlockStatus != memory_MAGICFREE) {
+
+    /* we expect block status to be either 
+       memory_MAGICMALLOC or memory_MAGICFREE.
+       Other values might result from overwriting,
+       trying to return an unallocated block,
+       or trying to return a block allocated with
+       another allocator.
+    */
+
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n In memory_CheckPointer:");
+    misc_UserErrorReport("\n Memory Error.");
+    misc_UserErrorReport(" Pointer %p was not (de)allocated by the module,",
+			 Pointer);
+    misc_UserErrorReport("\n or the memory block was corrupted.\n");
+    misc_FinishUserErrorReport();
+  }
+
+  if (BlockStatus == memory_MAGICMALLOC) {
+    if (BlockSize != Size) {
+      
+      /* we expect block size in a block´s debug
+	 information and given block size to match.
+      */
+
+      misc_StartUserErrorReport();
+      misc_UserErrorReport("\n In memory_CheckPointer:");
+      misc_UserErrorReport("\n Memory Error.");
+      misc_UserErrorReport(" Pointer %p was apparently allocated for",
+			   Pointer);
+      misc_UserErrorReport(" a block of size %d,",
+			   BlockSize);
+      misc_UserErrorReport("\n but it is expected to be a block of size %d.",
+			   Size);
+      misc_UserErrorReport("\n Probably the memory block was corrupted.\n");
+      misc_FinishUserErrorReport();
+
+      /* since the left dog tag seems to be corrupted we can not safely assume 
+	 that our memory info structure is still valid so we can't print it*/
+    }
+
+    if ((Size % memory_ALIGN) || (Size % memory__SHAREDPAGES)) {
+      /* check the fillbytes between used storage 
+	 and dog tag for overwriting */
+      char * ptr, * limit;
+      
+      limit    = (char *)Pointer + RealBlockSize;
+      
+      for (ptr = (char *)Pointer + Size; ptr < limit; ptr++) {
+	if (*ptr != memory__FREESHREDDER) {
+	  misc_StartUserErrorReport();
+	  misc_UserErrorReport("\n In memory_CheckPointer:");
+	  misc_UserErrorReport("\n Memory Error.");
+	  misc_UserErrorReport(" Pointer %p was allocated in file %s at line %d,",
+			       Pointer, Info->mallocInFile, Info->mallocAtLine);
+	  misc_UserErrorReport("\n for a block of size %d.",
+			       BlockSize);
+	  misc_UserErrorReport("\n The memory block was corrupted.\n");
+	  misc_FinishUserErrorReport();
+	}
+      }
+    }
+  }
+
+  if (Size >= memory__DYNMAXSIZE) {
+    /* we expect big blocks to be correctly linked */
+    MEMORY_BIGBLOCKHEADER BigBlockHeader;
+
+    BigBlockHeader = (MEMORY_BIGBLOCKHEADER) ((char *) Pointer - memory_OFFSET 
+					      - sizeof(MEMORY_BIGBLOCKHEADERNODE));
+
+    /* this test might crash the program
+       if something is wrong with the pointers,
+       so you may not get a message every time.
+    */
+    if (((BigBlockHeader->previous != NULL) 
+	 && (BigBlockHeader->previous->next != BigBlockHeader))
+	|| ((BigBlockHeader->previous == NULL) 
+	    && (memory_BIGBLOCKS != BigBlockHeader))
+	|| ((BigBlockHeader->next != NULL) 
+	    && (BigBlockHeader->next->previous != BigBlockHeader))) {
+      
+      misc_StartUserErrorReport();
+      misc_UserErrorReport("\n In memory_CheckPointer:");
+      misc_UserErrorReport("\n Memory Error.");
+      misc_UserErrorReport(" Pointer %p was not allocated by the module,",
+			   Pointer);
+      misc_UserErrorReport("\n or the memory block was corrupted.\n");
+      misc_FinishUserErrorReport();
+    }
+  }
+  
+  if (BlockStatus == memory_MAGICFREE) {
+    /* test if someone wrote over freed memory */
+    char * ptr, * limit;
+    
+    limit = (char *)Pointer + RealBlockSize;
+
+    for (ptr = (char *)Pointer + sizeof(POINTER); ptr < limit ; ptr++){
+      /* first sizeof(POINTER) bytes are reserved for the
+	 pointer to the next freed block in the list. All
+	 other bytes in the block should still have the value
+	 of memory__FREESHREDDER
+      */
+      if (*ptr != memory__FREESHREDDER) {
+	misc_StartUserErrorReport();
+	misc_UserErrorReport("\n In memory_CheckPointer:");
+	misc_UserErrorReport("\n Memory Error.");
+	misc_UserErrorReport(" Pointer %p was allocated in file %s at line %d",
+			     Pointer, Info->mallocInFile, Info->mallocAtLine);
+	misc_UserErrorReport("\n for a block of size %d",BlockSize);
+	misc_UserErrorReport("\n and freed in file %s at line %d.",
+			     Info->freeInFile, Info->freeAtLine);
+	misc_UserErrorReport("\n The memory block was used after deallocation.\n");
+	misc_FinishUserErrorReport();
+      }
+    }
+  }
+}
+
+void memory_CheckFree(POINTER Freepointer, unsigned int Size,
+		      unsigned int RealBlockSize, const char * File,
+		      unsigned short int Line)
+/**********************************************************
+   INPUT  : The pointer to be freed, the size of the block
+            it is supposed to point to, the real size of
+	    that block, the file and line where memory_Free
+	    was called.
+   RETURNS: None.
+   SUMMARY: Checks if memory management was initialized,
+            the given pointer is legal, and not freed
+	    already. It also zeroes the freed memory, and
+	    sets the block's debug and administration
+	    information.
+**********************************************************/
+{
+  MEMORY_INFO  Info;          /* block´s debug information      */
+
+  /* Check if memory management was initialized */
+  memory_CheckIfModuleIsInitialized("memory_Free", File, Line);
+
+  /* Check if given pointer is legal */
+  memory_CheckPointer(Freepointer, Size);
+
+  /* Check if current pointer is being freed for a second time */
+  memory_CheckIfPointerIsAlreadyFreed(Freepointer, "memory_Free", File, Line);
+
+  /* Set all bytes to zero, so we can detect overwriting of freed memory */
+  memset (Freepointer, memory__FREESHREDDER, RealBlockSize);
+
+  /* Get current block´s debug information */
+  Info = (MEMORY_INFO) ((char *) Freepointer - memory_OFFSET);
+
+  /* Set block´s debug and administration information */
+  memory_SetInfo(Info,Info->mallocInFile, Info->mallocAtLine, File, Line);
+  memory_SetBlockStatusAndSize(Freepointer, memory_MAGICFREE, Size);
+}
+#endif /* CHECK */
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  MALLOC                                                * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+#ifdef NO_MEMORY_MANAGEMENT
+
+POINTER memory_Malloc(unsigned int Bytes)
+{
+  char *mem; /* pointer to memory block obtained from malloc */
+
+  /* Pass the call through to compiler´s malloc */
+  mem = (char *)malloc(Bytes);
+
+  /* If malloc fails print an error message and exit */
+  if (mem == NULL) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n In memory_Malloc:");
+    misc_UserErrorReport("\n Memory Error. Out of memory.\n");
+    misc_FinishUserErrorReport();
+  }
+
+  return mem;
+}
+
+#else
+
+#ifdef CHECK
+POINTER memory_MallocIntern(unsigned int Bytes, 
+			    const char * File, 
+			    unsigned short int Line)
+#else
+POINTER memory_Malloc(unsigned int Bytes)
+#endif
+/********************************************************
+  INPUT  : The size of the requested memory block.      
+  RETURNS: A pointer to a block of <Bytes> bytes.       
+  SUMMARY: Allocates a memory block of requested length.
+  EXCEPT : Trying to allocate 0 bytes, violating a memory 
+           restriction, or running out of system memory 
+    	   cause the function to print an error message and 
+	   call exit().
+*********************************************************/
+{
+  char                *NewMemory;       /* pointer to allocated memory */
+
+  MEMORY_RESOURCE     *Resource;        /* current page resource,
+					   required if we do not allocate 
+					   a big block */
+
+#ifdef CHECK
+  MEMORY_INFO         NewInfo;          /* Storage for file and line 
+					   of allocation */
+#endif
+
+
+#ifdef CHECK
+  /* Is the module initialized? */
+  memory_CheckIfModuleIsInitialized("memory_Malloc", File, Line);
+
+  /* Is it a request for a block of zero bytes? */
+  if (Bytes == 0) {
+    /* The latest draft for the ANSI C 9X standard says in section 7.20.3:
+
+       "If the size of the space requested is zero, the behavior is
+        implementation-defined: either a null pointer is returned, or
+	the behavior is as if the size were some nonzero value,
+	except that the pointer shall not be used to access an object."
+
+	We have decided to print an error and exit upon such requests 
+	since they are often originated by a bug. 
+
+	Nonstandard but hopefully helpful.
+    */
+
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n In memory_Malloc:");
+    misc_UserErrorReport("\n Memory Error. Tried to allocate 0 Bytes!");
+    misc_UserErrorReport("\n Error occurred in memory_Malloc");
+    misc_UserErrorReport(" called from file %s at line %d.\n",
+			 File, Line);
+    misc_FinishUserErrorReport();
+  }
+#endif
+  
+  /* If it is a big block, then it has to be 
+     administrated in a special way 
+  */
+  if (Bytes >= memory__DYNMAXSIZE) {
+    unsigned int        RealBigBlockSize; /* real block size including 
+					     padding,header 
+					     and debug marks */
+
+    /* This is what a big block looks like:
+
+       --------------------------------------------------------------------
+       | MEMORY_BIGBLOCKHEADERNODE   | debug marks | char * | debug marks |
+       | previous and next big block |in debug mode| block  |in debug mode|
+       --------------------------------------------------------------------
+    */
+
+
+    /* Calculate the real size of the big block, 
+       from the size of administration information,
+       the size of debug marks and the requested block size
+    */
+
+    RealBigBlockSize = sizeof(MEMORY_BIGBLOCKHEADERNODE) + 
+      memory_MARKSIZE + memory_CalculateRealBlockSize(Bytes);
+
+    /* Check for violation of maximum allocation limit */
+    if (memory_MAXMEM >= 0) {
+      /* there is a maximum allocation limit, 
+	 let´s see if there is enough left 
+      */
+      if ((unsigned int)memory_MAXMEM < RealBigBlockSize) {
+	/* if it is not print an error message and exit */
+	misc_StartUserErrorReport();
+	misc_UserErrorReport("\n In memory_Malloc:");
+	misc_UserErrorReport("\n Memory Error.");
+	misc_UserErrorReport(" Terminated by user given memory restriction,\n");
+	misc_UserErrorReport("\n while trying to allocate %lu bytes.\n", 
+			     RealBigBlockSize);
+	misc_UserErrorReport("\n Maximum amount of memory");
+	misc_UserErrorReport(" left for allocation is %l bytes.\n", 
+			     memory_MAXMEM);
+#ifdef CHECK
+	misc_UserErrorReport("\n Error occurred in memory_Malloc");
+	misc_UserErrorReport(" called from file %s at line %d.\n",
+			     File, Line);
+#endif
+	misc_FinishUserErrorReport();
+      } 
+      else
+	/* otherwise subtract the real block size 
+	   from the amount of memory available for 
+	   allocation
+	*/
+	memory_MAXMEM -= RealBigBlockSize;
+    }
+
+    /* allocate a fresh block of memory via a call to malloc */
+    NewMemory = (char *)malloc(RealBigBlockSize);
+
+    /* Check if allocation was successful */
+    if (NewMemory != NULL) {
+
+      /* if it was, then administrate the fresh block:
+	 insert it into the big block list. The list 
+	 is double linked for fast deletion 
+      */
+
+      MEMORY_BIGBLOCKHEADER NewBigBlock; /* new block´s administration 
+					    information */
+
+      /* insert the fresh block as the first list element */
+      NewBigBlock = (MEMORY_BIGBLOCKHEADER) NewMemory;
+      NewBigBlock->next = memory_BIGBLOCKS;
+      NewBigBlock->previous = NULL;
+
+      /* if there are already elements in the big block list,
+	 change the first element´s pointer to the previous block
+	 to point to the fresh block´s administration information
+      */
+      if (memory_BIGBLOCKS != NULL) {
+	memory_BIGBLOCKS->previous = NewBigBlock;
+      }
+
+      /* reset the big block list pointer to point to the fresh block */ 
+      memory_BIGBLOCKS = NewBigBlock;
+
+      /* skip the administration information */
+      NewMemory += sizeof(MEMORY_BIGBLOCKHEADERNODE);
+
+#ifdef CHECK
+      /* set the debug information address */
+      NewInfo = (MEMORY_INFO) NewMemory;
+
+      /* skip left debug mark */
+      NewMemory += memory_OFFSET;
+#endif
+
+      /* add block´s real size to the total sum of allocated bytes */
+      memory_NEWBYTES    += RealBigBlockSize;
+    }
+    else {
+      /* NewMemory == NULL. 
+	 malloc could not allocate a memory block of required size,
+	 so we print an error message and exit 
+      */
+      misc_StartUserErrorReport();
+      misc_UserErrorReport("\n In memory_MallocIntern:");
+      misc_UserErrorReport("\n Memory Error. Out of memory.");
+      misc_UserErrorReport("\n Failed to allocate %d bytes.\n", 
+			   RealBigBlockSize);
+#ifdef CHECK
+      misc_UserErrorReport("\n Error occurred in memory_Malloc");
+      misc_UserErrorReport(" called from file %s at line %d.\n",
+			   File, Line);
+#endif
+      misc_FinishUserErrorReport();
+    }
+  }
+  else {
+    /* Bytes < memory__DYNMAXSIZE.
+       A memory request for a manageable size 
+    */
+
+    /* Initialize the memory resource for the given size */
+    Resource = memory_ARRAY[Bytes];
+
+
+    /* Check if there are freed blocks of that size */
+    if (*((int *)Resource->free) != EOF) {
+
+      /* if that is the case, then use an already freed block */
+
+      NewMemory                 = (char *) Resource->free;
+
+      /* update the free blocks list for that size */
+      Resource->free            = *((POINTER *)(NewMemory));
+
+      /* subtract block´s total size from the sum of freed bytes */
+      memory_FREEDBYTES        -= Resource->total_size;
+
+#ifdef CHECK
+      /* calculate the address of the block´s debug information */ 
+      NewInfo = (MEMORY_INFO) ((char*) NewMemory - memory_OFFSET);
+
+      /* Check if the block has been used after deallocation */
+      memory_CheckPointer(NewMemory, Bytes);  
+#endif
+    } 
+    else { 
+      /* there are no already freed blocks of that size */
+ 
+      /* Check if there is enough space left on current page */
+      if (Resource->next != Resource->end_of_page) {
+
+	/* if that is the case, then use a fresh block from current page */
+	NewMemory                = (char *)Resource->next;
+
+	/* update the pointer to the next usable block */
+	Resource->next           = NewMemory + Resource->total_size;
+
+	/* add block´s total size to the sum of allocated bytes */
+	memory_NEWBYTES         += Resource->total_size;
+
+#ifdef CHECK
+	/* Check if the fresh block´s address is sane */
+	if ((char *)NewMemory > (char *) Resource->end_of_page) {
+	  /* if it is not, then we have detected an internal error
+	     in the module itself. Oops! So we print an error message
+	     and abort, hoping that the core dump will enable us to 
+	     trace the error back to its origin
+	  */
+	  misc_StartErrorReport();
+	  misc_ErrorReport("\n In memory_Malloc:");
+	  misc_ErrorReport("\n Memory Error. Address overflow %d.",Bytes);
+	  misc_ErrorReport("\n Error occurred in memory_Malloc");
+	  misc_ErrorReport(" called from file %s at line %d.\n", File, Line);
+	  misc_FinishErrorReport();
+	}
+
+	/* if all is well, we initialize the pointer to fresh block´s
+	   debug information 
+	*/
+	NewInfo = (MEMORY_INFO)((char*) NewMemory - memory_OFFSET);
+#endif
+
+      } 
+      else { 
+	/* Check for violation of maximum allocation limit */
+	if (memory_MAXMEM >=0) {
+	  /* there is a maximum allocation limit, 
+	     let´s see if there is enough left
+	  */
+	  if ((unsigned int)memory_MAXMEM < memory_PAGESIZE) {
+	    /* if it is not, then print an error message and exit */
+	    misc_StartUserErrorReport();
+	    misc_UserErrorReport("\n In memory_Malloc:");
+	    misc_UserErrorReport("\n Memory Error.");
+	    misc_UserErrorReport(" Terminated by user given memory restriction.\n");
+#ifdef CHECK
+	    misc_UserErrorReport("\n Error occurred in memory_Malloc");
+	    misc_UserErrorReport(" called from file %s at line %d.\n",
+				 File, Line);
+#endif
+	    misc_FinishUserErrorReport();
+	  } 
+	  else {
+	    /* otherwise subtract the page size from the limit */
+	    memory_MAXMEM -= memory_PAGESIZE;
+	  }
+	}
+
+	/* try to allocate a new page via malloc */
+	NewMemory=(char *)malloc(memory_PAGESIZE);
+
+	/* check if allocation was successful */
+	if (NewMemory == NULL) {
+	  /* if it wasn´t print an error message and exit */
+	  misc_StartUserErrorReport();
+	  misc_UserErrorReport("\n In memory_Malloc:");
+	  misc_UserErrorReport("\n Memory Error.");
+	  misc_UserErrorReport(" Terminated, ran out of system memory.\n");
+#ifdef CHECK
+	  misc_UserErrorReport("\n Error occurred in memory_Malloc");
+	  misc_UserErrorReport(" called from file %s at line %d.\n",
+			       File, Line);
+#endif
+	  misc_FinishUserErrorReport();
+	}
+
+	/* otherwise administrate the fresh page,
+	   i.e insert it as the first element of the 
+	   page list for the given size 
+	*/
+	*((POINTER *)NewMemory)     = Resource->page;
+	Resource->page              = NewMemory;
+
+	/* add block´s total size to the sum of allocated bytes */
+	memory_NEWBYTES            += Resource->total_size;
+
+	/* set the end of page pointer for the fresh page */
+	Resource->end_of_page       = (char *) NewMemory + Resource->offset;
+
+	/* skip the page list */
+	NewMemory += sizeof(POINTER);
+
+#ifdef CHECK
+	/* set the debug information address */
+	NewInfo    = (MEMORY_INFO) NewMemory;
+
+	/* skip the left debug mark */
+	NewMemory += memory_OFFSET;
+#endif
+
+	/* update the pointer to the next usable block */	
+	Resource->next              = NewMemory + Resource->total_size;
+      }
+    }
+  }
+
+#ifdef CHECK
+  /* Set block´s debug information */
+  memory_SetInfo(NewInfo, File, Line, NULL, 0);
+  memory_SetBlockStatusAndSize(NewMemory,  
+			       memory_MAGICMALLOC, Bytes);
+
+  /* delete all block´s usable bytes with a shredder value */
+  memset(NewMemory, memory__FREESHREDDER,
+	 memory_LookupRealBlockSize(Bytes));
+#endif
+
+  return NewMemory;
+}
+
+#endif
+
+
+
+#ifdef NO_MEMORY_MANAGEMENT
+
+POINTER memory_Calloc(unsigned int Elements, unsigned int Bytes)
+{
+  char *mem; /* pointer to memory block obtained from calloc */
+
+  /* Pass call through to compiler´s calloc */
+  mem = (char *)calloc(Elements, Bytes);
+  
+  /* If calloc fails print an error message and exit */
+  if (mem == NULL) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n In memory_Calloc:");
+    misc_UserErrorReport("\n Memory Error. Out of memory.\n");
+    misc_FinishUserErrorReport();
+  }
+
+  return mem;
+}
+
+#else
+
+#ifdef CHECK
+POINTER memory_CallocIntern(unsigned int Elements, unsigned int Bytes, 
+			    const char * File, unsigned short int Line)
+#else
+POINTER memory_Calloc(unsigned int Elements, unsigned int Bytes)
+#endif
+/********************************************************
+  INPUT  : The number of requested equally huge blocks, 
+           and each block's size.
+  RETURNS: A pointer to a block of (Bytes * Elements) bytes.
+  SUMMARY: Allocates a memory block of requested length
+           filled with char value '\0'.
+*********************************************************/
+{
+  char       * mem; /* pointer to memory block obtained from the module */
+
+  /* Allocate memory via our memory management */
+#ifdef CHECK
+  mem = (char *)memory_MallocIntern(Elements * Bytes, File, Line);
+#else
+  mem = (char *)memory_Malloc(Elements * Bytes);
+#endif
+
+  /* If allocation was successful set all bytes to zero */ 
+  if (mem != NULL) {
+    memset(mem,0, Elements * Bytes);
+  }
+  /* otherwise print an error message and exit */
+  else {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n In memory_Calloc:");
+    misc_UserErrorReport("\n Memory Error. Out of memory.\n");
+#ifdef CHECK
+    misc_UserErrorReport("\n Error occurred in memory_Calloc");
+    misc_UserErrorReport(" called from file %s at line %d.\n",
+			 File, Line);
+#endif
+    misc_FinishUserErrorReport();
+  }
+
+  return mem;
+}
+#endif
+
+void memory_FreeAllMem(void) 
+/**************************************************************
+  INPUT  : None.
+  RETURNS: None.
+  SUMMARY: Frees all memory allocated by calls to the module.
+***************************************************************/
+{
+  int i;
+
+  /* delete all pages first by going through the memory_ARRAY.
+     This is slower than traversing the array memory_PAGES
+     directly, but is easier to implement correctly. Since
+     the only reasonable way to call memory_FreeAllMem is
+     before the program exits, a minimal performance penalty
+     should be acceptable
+  */
+
+  for (i = 1; i < memory__DYNMAXSIZE; i++) {
+    POINTER thispage, nextpage;
+    MEMORY_RESOURCE * Resource;
+
+    Resource = memory_ARRAY[i];
+
+    thispage = Resource->page;
+
+    if (*((int *)thispage) != EOF) {
+      do {
+	nextpage = *((POINTER *)thispage);
+	free(thispage);
+	thispage = nextpage;
+      } while  (*((int *)thispage) != EOF);
+
+      /* and reset the resource structure */
+      Resource->page        = &memory__EOF;
+      Resource->free        = &memory__EOF;
+      Resource->next        = &memory__EOF;
+      Resource->end_of_page = &memory__EOF;
+    }
+  }
+
+  /* now delete all big blocks left */
+
+  if (memory_BIGBLOCKS != NULL) {
+    MEMORY_BIGBLOCKHEADER thisblock, nextblock;
+    
+    for (thisblock = memory_BIGBLOCKS; 
+	 thisblock != NULL; 
+	 thisblock = nextblock) {
+      nextblock = thisblock->next;
+      free(thisblock);
+    }
+
+    /* and reset the list pointer */
+    memory_BIGBLOCKS = NULL;
+  }
+}
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  DEBUGGING INFORMATION                                 * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+void memory_Print(void)
+/**************************************************************
+  INPUT  : None.
+  RETURNS: None.
+  SUMMARY: Prints module status information to stdout:
+           the fixed size of an internal memory page, the size 
+	   of debug marks for a block of memory, the size of 
+	   demanded and freed memory in kilobytes, remaining 
+	   memory in bytes and the number of allocated pages of 
+	   memory.
+***************************************************************/
+{
+#ifndef NO_MEMORY_MANAGEMENT
+  /* Call memory_FPrint to print status information to stdout */
+  memory_FPrint(stdout);
+#endif
+}
+
+void memory_FPrint(FILE* File)
+/**************************************************************
+  INPUT  : A file pointer.
+  RETURNS: None.
+  SUMMARY: Prints module status information to given File:
+           the fixed size of an internal memory page, the size 
+	   of debug marks for a block of memory, the size of 
+	   demanded and freed memory in kilobytes, remaining 
+	   memory in bytes and the number of allocated pages of 
+	   memory.
+***************************************************************/
+{
+#ifndef NO_MEMORY_MANAGEMENT
+  int     Pages;    /* number of allocated pages                  */
+  int     i;
+  POINTER ActPage;  /* current page in page list for a block size */
+
+  /* Calculate the total number of pages */
+  Pages = 0;
+  for (i = 1; i < memory__DYNMAXSIZE; i+=memory__SHAREDPAGES) {
+    /* increase i by memory_SHAREDPAGES due to page sharing */
+    ActPage = memory_ARRAY[i]->page;
+
+    /* Traverse the page list */
+    while (*((int *)ActPage) != EOF) {
+      Pages++;
+      ActPage = *((POINTER *)ActPage);
+    }
+  }
+
+  /* Print status information */
+  fputs("\n###\n", File);
+  fprintf(File,"### Pagesize: %d\n",
+	  memory_PAGESIZE);
+  fprintf(File,"### Marksize: %d\n",
+	  (int)memory_MARKSIZE);
+  fprintf(File,"### Memory demanded:  %lu KBytes\n", 
+	  memory_NEWBYTES/memory__KILOBYTE);
+  fprintf(File,"### Memory freed:     %lu KBytes\n", 
+	  memory_FREEDBYTES/memory__KILOBYTE);
+  fprintf(File,"### Memory remaining: %lu Bytes\n", 
+	  memory_NEWBYTES-memory_FREEDBYTES);
+  fprintf(File,"### Pages allocated:  %d Pages\n", 
+	  Pages);
+  fputs("###\n", File);
+#endif
+}
+
+void memory_PrintAllocatedBlocks(unsigned int Size)
+/**************************************************************
+  INPUT  : Block size.
+  RETURNS: None.
+  SUMMARY: Prints addresses of allocated memory blocks with
+           given Size to stdout, if Size is less than 
+	   memory_DYNMAXSIZE.
+***************************************************************/
+{
+#ifndef NO_MEMORY_MANAGEMENT
+  MEMORY_RESOURCE *Resource;     /* current resource                   */
+
+  POINTER          ActPage;      /* current page                       */
+  POINTER          ActNext;      /* next usable block on current page */
+  POINTER          ActEndOfPage; /* end of current page                */
+
+  unsigned int     BlockSize;    /* current block size                 */
+
+#ifdef CHECK
+  MEMORY_INFO      Info;         /* current block´s debug information  */
+#endif
+
+  /* Allocated blocks are administered 
+     in two ways depending on their 
+     size. If the size is less than
+     memory__DYNMAXSIZE the block is
+     allocated from the appropriate
+     page. Otherwise the block is 
+     allocated directly via a call
+     to malloc or calloc.
+
+     Thus we have two functions to
+     print the allocated blocks:
+     memory_PrintAllocatedBlocks and
+     memory_PrintAlocatedBigBlocks.
+  */
+
+
+  /* Check if memory_PrintAllocatedBlocks has been called for
+     a legal block size
+  */
+
+  if (Size >= memory__DYNMAXSIZE) {
+    /* if that´s not the case print an error message and exit */
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n In memory_PrintAllocatedBlocks:");
+    misc_UserErrorReport("\n Parameter size is too big: %d.",
+			 Size);
+    misc_UserErrorReport("\n Maximal allowed value is: %d.\n", 
+			 memory__DYNMAXSIZE);
+    misc_FinishUserErrorReport();
+  }
+  else {
+    /* otherwise size is legal */
+
+    /* initialize the variables */
+    Resource     = memory_ARRAY[Size];
+    ActPage      = Resource->page;
+    ActNext      = Resource->next;
+    ActEndOfPage = Resource->end_of_page;
+    BlockSize    = Resource->total_size;
+
+    /* Test if there were any requests made for blocks of that size */
+    if (*((int *)ActPage) == EOF) {
+      /* Check if pointers are consistent */
+      if (*((int *)ActNext) == EOF) {
+	/* If that is true, print that information to stdout */
+	puts("   No request so far");
+      }
+      else {
+	/* Otherwise print an error message and abort */
+	 misc_StartErrorReport();
+	 misc_ErrorReport("\n In memory_PrintAllocatedBlocks:");
+	 misc_ErrorReport("\n Memory Error. No Page entry but Next entry.\n");
+	 misc_FinishErrorReport();
+      }
+    }
+    else {
+      /* We have received some requests for blocks of that size */ 
+#ifdef CHECK
+
+      POINTER ActData; /* current block */
+
+
+      /* Traverse through the page list for given block size */
+      while (*((int *)ActPage) != EOF) {
+
+	/* Initialize the variables */
+	ActData      = (char *)ActPage + sizeof(POINTER) + memory_OFFSET;
+	ActEndOfPage = (char *)ActPage + Resource->offset;
+
+	/* Visit blocks on current page until the end of
+	   page is reached, or an allocated block is found
+	*/
+	while (ActData != ActNext 
+	       && ActData != ActEndOfPage
+	       && memory_GetBlockStatus(ActData) != memory_MAGICMALLOC) {
+	  ActData = (char *)ActData + BlockSize;
+	}
+
+	/* Check if there were any allocated blocks from current page */
+	if (ActData == ActNext || ActData == ActEndOfPage) {
+	  /* if that´s not the case print the information to stdout */
+	  printf("\n\n   No memory allocated from page at address %p\n", ActPage);
+	}
+	else {
+	  /* otherwise print address and origin of (de)allocation of
+	     all allocated blocks on current page, starting
+	     with the block just found
+	  */
+	  fputs("\n\n   Allocated but not freed: ", stdout);
+	  do  {
+	    Info = (MEMORY_INFO) ((char *) ActData - memory_OFFSET);
+	    if (memory_GetBlockStatus(ActData) == memory_MAGICMALLOC 
+		&& memory_GetBlockSize(ActData) == Size) {
+	      printf("\n\t%p allocated in file %s at line %d ", 
+		     ActData, Info->mallocInFile, Info->mallocAtLine);
+	    }
+	    ActData = (char *)ActData + BlockSize;
+	  } while (ActData != ActNext && ActData != ActEndOfPage);
+	}
+
+	/* go to the next page in the page list for given block size */
+	ActPage = *((POINTER *)ActPage);
+      }
+#endif
+    }
+  }
+#endif
+}
+
+void memory_PrintFreedBlocks(unsigned int Size)
+/**************************************************************
+  INPUT  : Block size.
+  RETURNS: None.
+  SUMMARY: Prints addresses of freed memory blocks with given 
+           Size to stdout, if Size is less than 
+	   memory_DYNMAXSIZE.
+***************************************************************/
+{
+#ifndef NO_MEMORY_MANAGEMENT
+  POINTER     ActFree; /* current block */
+
+#ifdef CHECK
+  MEMORY_INFO Info;    /* current block´s debug information */
+#endif
+
+  /* since we don´t recycle blocks whose size is
+     greater or equal to memory__DYNMAXSIZE, 
+     memory_PrintFreedBlocks is meaningless
+     for such block sizes.
+  */
+
+  /* test if given block size is legal */
+  if (Size >= memory__DYNMAXSIZE) {
+    /* if that´s not the case print an error message and exit */
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n In memory_PrintFreedBlocks.");
+    misc_UserErrorReport("\n Parameter Size is too big: %d.", 
+			 Size);
+    misc_UserErrorReport("\n Maximal allowed value is: %d.\n", 
+			 memory__DYNMAXSIZE);
+    misc_FinishUserErrorReport();
+  }
+  else {
+    /* otherwise size is legal */
+
+    /* start at the first element of the free block list
+       for the given block size
+    */
+    ActFree = memory_ARRAY[Size]->free;
+
+    /* test if the free block list is empty */
+    if (*((int *)ActFree) == EOF) {
+      /* if that´s true, print that information to stdout */
+      puts("\n\n   No freed memory");
+    }
+    else {
+      /* otherwise traverse the list of freed blocks */
+
+      fputs("\n\n   Free: ", stdout);
+      while (*((int *)ActFree) != EOF) {
+#ifdef CHECK
+	/* in debug mode print current block´s address
+	   and origin of (de)allocation
+	*/
+
+	/* check if block´s size is correct */ 
+	if ( memory_GetBlockSize(ActFree) == Size) {
+	  /* if that´s true than print block´s information */
+	  Info = (MEMORY_INFO) ((char *) ActFree - memory_OFFSET);
+	  printf("\n\t%p\tallocated in file %s at line %d",
+		 ActFree,  Info->mallocInFile, Info->mallocAtLine);
+	  printf("\n\t\tfreed in file %s at line %d",
+		 Info->freeInFile, Info->freeAtLine);
+	}
+	else {
+	  /* otherwise if we are sharing pages among different
+	     block sizes, the block is uncorrupted, despite not 
+	     matching assumed and real size. But if we are
+	     not sharing pages then the block is probably corrupted, 
+	     so print an error message and exit 
+	  */
+
+	  /* test if we are not in page sharing mode */
+	  if (memory__SHAREDPAGES == 1) {
+	    /* if that´s true print an error message and exit */
+	    misc_StartUserErrorReport();
+	    misc_UserErrorReport("\n In memory_PrintFreedBlocks:");
+	    misc_UserErrorReport("\n Memory Error. Memory block size mismatch.");
+	    misc_UserErrorReport("\n Expected %d found %d for memory block at %p.\n",
+				 Size, memory_GetBlockSize(ActFree), ActFree);
+	    misc_UserErrorReport("\n Probably the memory block was corrupted.\n");	    
+	    misc_FinishUserErrorReport();
+	  }
+	}
+
+#endif
+
+	/* go to the next free block in list */
+	ActFree = *((POINTER *)ActFree);
+      }
+    }
+  }
+#endif
+}
+
+
+void memory_PrintAllocatedBigBlocks(void)
+/**************************************************************
+  INPUT  : None.
+  RETURNS: None.
+  SUMMARY: Prints addresses of all allocated memory blocks,
+           that are greater than memory_DYNMAXSIZE to stdout.
+***************************************************************/
+{
+#ifndef NO_MEMORY_MANAGEMENT
+#ifdef CHECK
+  MEMORY_BIGBLOCKHEADER Ptr;         /* current big block in list */
+  MEMORY_INFO           Info;        /* block´s debug information */
+  char                * BlockStart;  /* block´s start address     */
+  
+  /* start with the first block in the big block list */
+  Ptr = memory_BIGBLOCKS;
+
+  /* check whether big block list isn´t empty */
+  if (Ptr != NULL) {
+    /* if that´s the case traverse through the list
+       and print each block´s address, size and
+       origin of (de)allocation information
+    */
+    do {
+      BlockStart = (char *)Ptr + memory_OFFSET 
+	+ sizeof(MEMORY_BIGBLOCKHEADERNODE);
+      
+      Info = (MEMORY_INFO) (BlockStart - memory_OFFSET);
+      printf("\n\t%p %d bytes allocated in file %s at line %d ", 
+	     (void*)BlockStart, memory_GetBlockSize(BlockStart),
+	     Info->mallocInFile, Info->mallocAtLine);
+      Ptr = Ptr->next;
+    } while (Ptr != NULL);
+    puts("");
+  }
+  else {
+    /* otherwise there are no big blocks allocated */
+    puts("   No request so far");
+  }
+#endif
+#endif
+}
+
+void memory_PrintDetailed(void)
+/**************************************************************
+  INPUT  : None.
+  RETURNS: None.
+  SUMMARY: Prints addresses of all pages, and allocated and freed 
+           blocks on them.
+***************************************************************/
+{
+#ifndef NO_MEMORY_MANAGEMENT
+  MEMORY_RESOURCE  *Resource;     /* current resource                      */
+
+  POINTER           ActPage;      /* current page                          */
+  POINTER           ActData;      /* current block                         */
+  POINTER           ActEndOfPage; /* end of current page                   */
+  unsigned int      BlockSize;    /* total size of a block of current size */
+  unsigned int      PageOffset;   /* current page´s offset                 */
+
+  unsigned int      i;
+
+
+  /* print end-of-memory pointer´s address */
+  printf("\n\nEOF Pointer: %p\n", (void*)&memory__EOF);
+
+  /* for all administrated block sizes print detailed information */
+  for (i=1; i<memory__DYNMAXSIZE; i++) {
+    /* initialize variables for requested block size i */
+    Resource     = memory_ARRAY[i];
+    ActPage      = Resource->page;
+    ActData      = Resource->next;
+    ActEndOfPage = Resource->end_of_page;
+    PageOffset   = Resource->offset;
+    BlockSize    = Resource->total_size;
+
+    /* print requested block size, aligned block size 
+       and block size including debug marks
+    */
+    printf("\n\n Entry: %d aligned size: %d total size: %d\n", 
+	   i , Resource->aligned_size, BlockSize);
+
+    /* Check if there were any requests for blocks of size i */
+    if (*((int *)ActPage) == EOF) {
+      /* if that´s not the case check if memory management is consistent */
+      if (*((int *)ActData) == EOF) {
+	/* if that´s true, print that no requests occurred to stdout */
+	puts("   No request so far");
+      }
+      else {
+	/* our memory management is no longer consistent, 
+	   so print an error message and abort. We hope that
+	   the core dump will help us to find the bug
+	*/
+	misc_StartErrorReport();
+	misc_ErrorReport("\n In memory_PrintDetailed:");
+	misc_ErrorReport("\n Memory Error. No Page entry but Next entry.\n");
+	misc_FinishErrorReport();
+      }
+    }
+    else {
+      /* we have received requests for blocks of size i */
+
+      /* traverse the list of pages for size i */
+      while (*((int *)ActPage) != EOF) {
+	/* print information about current page */
+	printf("\n\n   Page: %p Next Page: %p\n",
+	       ActPage, *((POINTER *)ActPage));
+
+	/* initialize variables for current page */
+	ActData = ((char *)ActPage + sizeof(POINTER) + memory_OFFSET);
+	ActEndOfPage = (char *)ActPage + PageOffset;
+
+	/* print addresses of all blocks on current page */
+	fputs("   Data: ", stdout);
+	while (ActData != ActEndOfPage) {
+	  int column;
+
+	  fputs("\n\t\t", stdout);
+	  for (column = 0; column < 6; column++) {
+	    printf("%p ", ActData);
+	    ActData = (char *)ActData + BlockSize;
+	    if (ActData == ActEndOfPage) {
+	      break;
+	    }
+	  }
+	}
+
+	/* go to next page in list */
+	ActPage = *((POINTER *)ActPage);
+      }
+
+      /* print allocated and freed blocks of size i */
+      memory_PrintAllocatedBlocks(i);
+      memory_PrintFreedBlocks(i);
+    }
+  }
+
+#ifdef CHECK
+  /* print allocated blocks of size >= memory_DYNMAXSIZE */
+  printf("\n\n Allocated blocks of size >= %d\n", 
+	 memory__DYNMAXSIZE);
+  memory_PrintAllocatedBigBlocks();
+#endif
+#endif
+}
+
+
+void memory_PrintLeaks(void)
+/**************************************************************
+  INPUT  : None.
+  RETURNS: None.
+  SUMMARY: Prints addresses of all allocated blocks. Should be
+           used at the end of a program before the call to
+	   memory_FreeAllMem.
+***************************************************************/
+{
+#ifndef NO_MEMORY_MANAGEMENT
+  POINTER           ActPage;       /* current page                     */
+  POINTER           ActNext;       /* next fresh block on current page */
+  POINTER           ActEndOfPage;  /* end of current page              */
+  MEMORY_RESOURCE  *Resource;      /* current resource                 */
+  unsigned int      Size;          /* current size                     */
+  unsigned int      BlockSize;     /* total block size                 */
+
+  /* Check if some memory is still allocated */ 
+  if (memory_UsedBytes() != 0L) { 
+
+    /* If that´s true, print all allocated blocks  */
+
+    /* Start with blocks administered by our memory management */
+    for (Size = 1; Size < memory__DYNMAXSIZE; Size++) {
+      /* Initialize variables for current block size */
+      Resource     = memory_ARRAY[Size];
+      ActPage      = Resource->page;
+      ActNext      = Resource->next;
+      ActEndOfPage = Resource->end_of_page;
+      BlockSize    = Resource->total_size;
+
+      /* Check if there were any requests for 
+	 memory blocks of that size */
+      if (*((int *)ActPage) != EOF) {
+      
+	/* if that´s true, browse through all blocks on all pages
+	   to find a block that is still allocated
+	*/
+#ifdef CHECK
+	
+	POINTER ActData;
+	BOOL    LeakFound;
+	
+	LeakFound = FALSE;
+	
+	while (*((int *)ActPage) != EOF) {
+	  
+	  /* search through all pages for a block that is still allocated */
+	  
+	  ActData      = (char *)ActPage + sizeof(POINTER) + memory_OFFSET;
+	  ActEndOfPage = (char *)ActPage + Resource->offset;
+	  
+	  while (ActData != ActNext && ActData != ActEndOfPage) {
+	    if (memory_GetBlockStatus(ActData) == memory_MAGICMALLOC) {
+	      LeakFound = TRUE;
+	      break;
+	    }
+	    ActData = (char *)ActData + BlockSize;
+	  }
+	  
+	  if (LeakFound) {
+	    
+	    /* if we have found one, than call memory_PrintAllocatedBlocks
+	       to print its address */
+	    
+	    printf("\n\n  Leaked blocks of size %d:", Size);
+	    
+	    memory_PrintAllocatedBlocks(Size);
+	    putchar('\n');
+	    /* since memory_PrintAllocatedblocks prints 
+	     *all* allocated blocks of specific size, we can
+	     break out of the while loop
+	    */
+	    break;
+	  }
+	  else {
+	    /* go to next page */
+	    ActPage = *((POINTER *)ActPage);
+	  }
+	}
+
+#endif
+
+      }      
+    }
+
+#ifdef CHECK
+    /* Print allocated blocks of size >= memory__DYNMAXSIZE */
+    if (memory_BIGBLOCKS != NULL) {
+      printf("\n\n  Leaked blocks of size >= %d\n", 
+	     memory__DYNMAXSIZE);
+      memory_PrintAllocatedBigBlocks();
+      putchar('\n');
+    }
+#endif
+
+  }
+#endif
+}
diff --git a/test/spass/memory.h b/test/spass/memory.h
new file mode 100644
index 0000000000000000000000000000000000000000..d0edac187bcc8601aaf2a3ff393a0f5e2986ee71
--- /dev/null
+++ b/test/spass/memory.h
@@ -0,0 +1,478 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *        DYNAMIC MEMORY MANAGEMENT MODULE                * */
+/* *                                                        * */
+/* *  $Module:   MEMORY                                     * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#ifndef _MEMORY_
+#define _MEMORY_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "misc.h"
+
+/**************************************************************/
+/* Data structures and constants                              */
+/**************************************************************/
+
+#ifndef memory__DYNMAXSIZE
+#define memory__DYNMAXSIZE   1024 /* At most blocks of size memory__DYNMAXSIZE
+				     bytes are administrated by the
+				     module, larger requests are
+				     directly mapped to system calls */
+#endif
+
+#ifndef memory__SHAREDPAGES
+#define memory__SHAREDPAGES    1  /* Number of block sizes sharing an allocated 
+				     page. By setting memory__SHAREDPAGES to 4, 
+				     the module would administrate requests 
+				     for 1, 2, 3 and 4 bytes on the same set of 
+				     pages, requests for 5, 6, 7 and 8 on another 
+				     one, etc. By default every block size has 
+				     its own set of pages */
+#endif
+
+#ifndef memory__FREESHREDDER
+#define memory__FREESHREDDER  'S' /*  The decimal number 83, which can also be 
+				      read as 53 hexadecimal, or the character 
+				      'S' in ASCII code */
+#endif
+
+#define memory__KILOBYTE        1024
+
+#ifndef memory__DEFAULTPAGESIZE
+#define memory__DEFAULTPAGESIZE (8 * memory__KILOBYTE)
+                                  /* Used to set the default size of a page. 
+				     If the default page size is too small to 
+				     contain two objects of size memory__DYNMAXSIZE
+				     the default page size is automatically 
+				     increased by the function memory_Init */
+#endif
+
+#ifndef memory__UNLIMITED
+#define memory__UNLIMITED       (-1)
+                                  /* Used to set the maximal amount of memory
+				     available for the memory module to
+				     "unlimited" when calling memory_Init. */
+#endif
+
+typedef struct MEMORY_RESOURCEHELP {
+  POINTER free;                    /* pointer to the next free block in list  */
+  POINTER next;                    /* pointer to the next fresh block         */
+  POINTER page;                    /* pointer to head of page list            */
+  POINTER end_of_page;             /* pointer to the end of current page      */
+  int     total_size;              /* total block size inc. debug marks       */
+  int     aligned_size;            /* block size without debug marks          */
+  int     offset;                  /* offset of last usable block on page     */
+} MEMORY_RESOURCE;
+
+extern MEMORY_RESOURCE * memory_ARRAY[];
+
+#if defined(CHECK)
+typedef struct MEMORY_INFOHELP {
+  const char * mallocInFile;       /* origin of allocation request:   file    */
+  const char * freeInFile;         /* origin of deallocation request: file    */
+  unsigned short int mallocAtLine; /* origin of allocation request:   line    */
+  unsigned short int freeAtLine;   /* origin of deallocation request: line    */
+} MEMORY_INFONODE, * MEMORY_INFO;
+
+#endif
+
+typedef struct MEMORY_BIGBLOCKHEADERHELP {
+  struct MEMORY_BIGBLOCKHEADERHELP * previous, * next;
+} MEMORY_BIGBLOCKHEADERNODE, * MEMORY_BIGBLOCKHEADER;
+
+extern long                  memory_MAXMEM;
+
+extern unsigned long         memory_NEWBYTES;
+extern unsigned long         memory_FREEDBYTES;
+
+extern const unsigned int    memory_MAGICMALLOC;
+extern const unsigned int    memory_MAGICFREE;
+
+extern const unsigned int    memory_ALIGN;
+
+extern MEMORY_BIGBLOCKHEADER memory_BIGBLOCKS;
+
+/**************************************************************/
+/* Debug Information                                          */
+/**************************************************************/
+
+extern unsigned int memory_MARKSIZE;
+extern unsigned int memory_OFFSET;
+
+/**************************************************************/
+/* Check Functions                                            */
+/**************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef CHECK
+void    memory_CheckFree(POINTER Freepointer, unsigned int Size, unsigned int RealBlockSize, const char * File, unsigned short int Line);
+#endif /* CHECK */
+
+#ifdef __cplusplus
+}
+#endif
+
+/**************************************************************/
+/* Inline Functions                                           */
+/**************************************************************/
+
+
+static __inline__ unsigned int memory_CalculateRealBlockSize(unsigned int 
+							     BlockSize)
+/**********************************************************
+  INPUT  : Size of a block of memory.
+  RETURNS: its real size.
+  SUMMARY: Calculates the size of a memory block, 
+           including padding due to memory alignment and
+           page sharing
+**********************************************************/
+{  
+  unsigned int RealSize;
+
+  RealSize = BlockSize;
+
+  if (RealSize % memory__SHAREDPAGES) {
+    RealSize += memory__SHAREDPAGES - (RealSize % memory__SHAREDPAGES);
+  }
+
+  if (RealSize % memory_ALIGN) {
+    RealSize += memory_ALIGN - (RealSize % memory_ALIGN);
+  }
+
+  return RealSize;
+
+}
+
+static __inline__ unsigned int memory_LookupRealBlockSize(unsigned int 
+							  BlockSize)
+/**********************************************************
+  INPUT  : Size of a block of memory.
+  RETURNS: its real size.
+  SUMMARY: Returns the size of a memory block, 
+           including padding due to memory alignment and
+           page sharing.
+**********************************************************/
+{  
+
+  unsigned int RealSize;
+
+  if (BlockSize < memory__DYNMAXSIZE) {
+    RealSize = memory_ARRAY[BlockSize]->aligned_size;
+  }
+  else {
+    RealSize = memory_CalculateRealBlockSize(BlockSize);
+  }
+
+  return RealSize;
+
+}
+
+#ifdef CHECK
+static __inline__ void memory_SetBlockStatusAndSize(POINTER Mem, 
+						    unsigned int Status,
+						    unsigned int Size)
+/**********************************************************
+  INPUT  : a pointer to a block of memory, its status
+           (memory_MAGICMALLOC or memory_MAGICFREE), and
+           size.
+  RETURNS: None.
+  SUMMARY: Sets a status flag (memory_MAGICMALLOC or
+           memory_MAGICFREE) and block size.
+**********************************************************/
+{
+  *((int *)Mem - 1) = Size; 
+  *((int *)((char *)Mem + memory_LookupRealBlockSize(Size))) = Status;
+}
+
+static __inline__ unsigned int memory_GetBlockSize(POINTER Mem)
+/**********************************************************
+  INPUT  : A pointer to a block of memory.
+  RETURNS: its size.
+  SUMMARY: Returns the size of a memory block.
+**********************************************************/
+{
+  return *((int *)Mem - 1);
+}
+
+static __inline__ unsigned int memory_GetRealBlockSize(POINTER Mem)
+/**********************************************************
+  INPUT  : A pointer to a block of memory.
+  RETURNS: its real size.
+  SUMMARY: Returns the real size of a memory block,
+           including padding bytes.
+**********************************************************/
+{
+  return memory_LookupRealBlockSize(memory_GetBlockSize(Mem));
+}
+
+static __inline__ unsigned int memory_GetBlockStatus(POINTER Mem) 
+/**********************************************************
+  INPUT  : A pointer to a block of memory.
+  RETURNS: its status.
+  SUMMARY: Returns the status of a memory block.
+**********************************************************/
+{
+  unsigned int Size;
+
+  Size = memory_GetBlockSize(Mem); 
+
+  return  *((int *)((char *)Mem + memory_LookupRealBlockSize(Size)));
+}
+
+static __inline__ void memory_SetInfo(MEMORY_INFO Info,
+				      const char * MallocInFile,
+				      unsigned short int MallocAtLine,
+				      const char * FreeInFile,
+				      unsigned short int FreeAtLine)
+/**********************************************************
+  INPUT  : a memory info structure, strings for files where
+           the block was allocated and freed, and short 
+	   integers for the corresponding lines.
+  RETURNS: None.
+  SUMMARY: Sets the debugging information for a memory block
+**********************************************************/
+{
+  if (!Info) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In memory_SetInfo:");
+    misc_ErrorReport("\n Memory Error. Info is a NULL pointer.\n");
+    misc_FinishErrorReport();
+  }
+ 
+  Info->mallocAtLine   = MallocAtLine;
+  Info->mallocInFile   = MallocInFile;
+  Info->freeAtLine     = FreeAtLine;
+  Info->freeInFile     = FreeInFile;
+}
+#endif
+
+static __inline__ unsigned long memory_DemandedBytes(void)
+/**********************************************************
+  INPUT  : Nothing.
+  RETURNS: Maximum number of bytes allocated at the same 
+           time by the module.
+  SUMMARY: Returns maximum number of allocated bytes at the
+           same time.
+**********************************************************/
+{
+  return memory_NEWBYTES;
+}
+
+
+static __inline__ unsigned long memory_UsedBytes(void)
+/**********************************************************
+  INPUT  : Nothing.
+  RETURNS: Number of bytes currently in use by your program.
+  SUMMARY: Returns number of bytes currently allocated.
+**********************************************************/
+{
+  return memory_NEWBYTES-memory_FREEDBYTES;
+}
+
+#ifdef NO_MEMORY_MANAGEMENT
+
+static __inline__ void memory_Free(POINTER Freepointer, unsigned int Size)
+{
+  free((char*)Freepointer);
+}
+
+#else
+
+#ifdef CHECK
+static __inline__ void memory_FreeIntern(POINTER  Freepointer, 
+					 unsigned int Size, 
+					 const char * File, 
+					 unsigned short int Line)
+#else
+static __inline__ void memory_Free(POINTER Freepointer, unsigned int Size)
+#endif
+/**********************************************************
+  INPUT  : Pointer to the block of memory to be freed, 
+           and the block's size
+  RETURNS: Nothing.
+  SUMMARY: Frees a block of memory for reallocation.
+           This function performs correctness checks
+	   in debugging mode.
+**********************************************************/
+{ 
+  unsigned int RealBlockSize; /* block´s alignment correct size */
+
+  RealBlockSize = memory_LookupRealBlockSize(Size);
+
+#ifdef CHECK
+  memory_CheckFree(Freepointer, Size, RealBlockSize, File, Line);
+#endif
+
+
+  /* Check if current block is a big block */ 
+  if (Size >= memory__DYNMAXSIZE) {
+    /* if that´s true, remove it from the double linked big block list */
+    MEMORY_BIGBLOCKHEADER BigBlockHeader;
+
+    BigBlockHeader = 
+      (MEMORY_BIGBLOCKHEADER) ((char *) Freepointer - memory_OFFSET
+			       - sizeof(MEMORY_BIGBLOCKHEADERNODE));
+
+    /* Check if current big block is the first block in the list */
+    if (BigBlockHeader->previous != NULL) {
+      /* if that´s not true, set previous block´s successor
+	 to current block´s successor
+      */
+      BigBlockHeader->previous->next = BigBlockHeader->next;
+    }
+    else {
+      /* otherwise set the first block in the big blocks list
+	 to current block´s successor
+      */
+      memory_BIGBLOCKS = BigBlockHeader->next;
+    }
+
+    /* Check if current block is the last block in the list */
+    if (BigBlockHeader->next != NULL) {
+      /* if that´s not true, set next block´ predecessor to
+	 current block´s predecessor 
+      */
+      BigBlockHeader->next->previous = BigBlockHeader->previous;
+    }
+
+    /* Adapt total number of freed bytes 
+       and number of bytes available for allocation
+       accordingly
+    */
+    memory_FREEDBYTES       += RealBlockSize + memory_MARKSIZE + 
+      sizeof(MEMORY_BIGBLOCKHEADERNODE);
+
+    if (memory_MAXMEM >= 0) {
+      memory_MAXMEM           += RealBlockSize + memory_MARKSIZE + 
+	sizeof(MEMORY_BIGBLOCKHEADERNODE);
+    }
+
+    /* pass the call though to free() with correct pointer value */
+#ifdef CHECK
+    free((char *)Freepointer - memory_OFFSET 
+	 - sizeof(MEMORY_BIGBLOCKHEADERNODE));
+#else
+    free((char*) Freepointer - sizeof(MEMORY_BIGBLOCKHEADERNODE));
+#endif
+  }
+  else {
+    /* current block is not a big block */
+    /* Adapt number of allocated bytes 
+       and the freed blocks list accordingly 
+    */
+    memory_FREEDBYTES       += memory_ARRAY[Size]->total_size;
+    *(POINTER *)Freepointer  = memory_ARRAY[Size]->free;
+    memory_ARRAY[Size]->free = Freepointer;
+  }
+
+}
+
+#endif
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+void    memory_Init(long);
+void    memory_Restrict(long);
+
+void    memory_Print(void);
+void    memory_FPrint(FILE*);
+  
+void    memory_PrintLeaks(void);
+void    memory_PrintDetailed(void);
+void    memory_PrintAllocatedBlocks(unsigned int Size);
+void    memory_PrintFreedBlocks(unsigned int Size);
+void    memory_PrintAllocatedBigBlocks(void);
+  
+void    memory_FreeAllMem(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(CHECK) && !defined(NO_MEMORY_MANAGEMENT)
+/* declare drop-in debug versions memory functions */
+#ifdef __cplusplus
+extern "C" {
+#endif
+POINTER memory_MallocIntern(unsigned int, const char *, unsigned short int);
+POINTER memory_CallocIntern(unsigned int,
+			    unsigned int, 
+			    const char *, 
+			    unsigned short int);
+#ifdef __cplusplus
+}
+#endif
+#define memory_Malloc(Size) memory_MallocIntern((Size), __FILE__, __LINE__)
+#define memory_Calloc(Elements, Size) \
+memory_CallocIntern((Elements), (Size), __FILE__, __LINE__)
+#define memory_Free(Pointer, Size) \
+memory_FreeIntern((Pointer), (Size), __FILE__, __LINE__)
+#else
+#ifdef __cplusplus
+extern "C" {
+#endif
+POINTER memory_Malloc(unsigned int);
+POINTER memory_Calloc(unsigned int, unsigned int);
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif
diff --git a/test/spass/misc.c b/test/spass/misc.c
new file mode 100644
index 0000000000000000000000000000000000000000..3a63396d77accb05f4ac8cbda2f81ea4ff3094ea
--- /dev/null
+++ b/test/spass/misc.c
@@ -0,0 +1,147 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                MISCELLANEOUS                           * */
+/* *                                                        * */
+/* *  $Module:   MISC                                       * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "misc.h"
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+#if 0
+void misc_ErrorReport(const char * Format, ...)
+{
+  va_list args;
+  va_start(args,Format);
+  vfprintf(misc_ERROROUT,Format,args);
+  va_end(args);
+}
+
+void misc_UserErrorReport(const char * Format, ...)
+{
+  va_list args;
+  va_start(args,Format);
+  vfprintf(misc_USERERROROUT,Format,args);
+  va_end(args);
+}
+#endif
+
+void misc_DumpCoreOut(const char* String)
+/**************************************************************
+  INPUT:   A  string.
+  RETURNS: Nothing.
+  EFFECT:  Prints <String> and then dumps a core.
+***************************************************************/
+{
+  fprintf(stderr, "\n %s \n", String);
+  misc_DumpCore();
+}
+
+
+
+int misc_ReturnValue(void)
+{
+  return 0;
+}
+
+
+int misc_Max(int a, int b)
+{
+  if (a > b)
+    return a;
+  else
+    return b;
+}
+
+FILE* misc_OpenFile(const char* Name, const char* Mode)
+/**************************************************************
+  INPUT:   The name of a file and a string containing the mode
+           for opening the file (see fopen(3)).
+           Examples for Mode are "r" for reading and "w" for writing.
+  RETURNS: The FILE pointer, if the file was successfully opened.
+  EFFECT:  If it wasn't possible to open the file with the
+           requested mode, an error message is printed and the
+           program exits.
+***************************************************************/
+{
+  FILE* File;
+
+  File = fopen(Name,Mode);
+
+  if (File == (FILE*)NULL) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n\tError in opening file %s for %s !\n\n", Name, 
+			 (Mode[0] == 'r' ? "reading" :
+			  (Mode[0] == 'w' ? "writing" : "i/o operations")));
+    misc_FinishUserErrorReport();
+  }  
+
+  return File;
+}
+
+void misc_CloseFile(FILE* File, const char* Name)
+/**************************************************************
+  INPUT:   A FILE and its name.
+  RETURNS: Nothing.
+  EFFECT:  Closes the file. If an error occurs, a message is
+           printed and the program exits.
+***************************************************************/
+{
+  int Result;
+
+  Result = fclose(File);
+
+  if (Result != 0) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n\tError in closing file %s !\n\n", Name);
+    misc_FinishUserErrorReport();
+  }  
+}
+
diff --git a/test/spass/misc.h b/test/spass/misc.h
new file mode 100644
index 0000000000000000000000000000000000000000..69d929d1be7ff937898447a6250652f5f3077165
--- /dev/null
+++ b/test/spass/misc.h
@@ -0,0 +1,161 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                MISCELLANEOUS                           * */
+/* *                                                        * */
+/* *  $Module:   MISC                                       * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                       * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _MISC_
+#define _MISC_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#define __USE_FIXED_PROTOTYPES__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <limits.h>
+#include <stdarg.h>
+
+/**************************************************************/
+/* More basic types and macros                                */
+/**************************************************************/
+
+#if defined(TRUE)
+#undef TRUE
+#endif
+
+#if defined(FALSE)
+#undef FALSE
+#endif
+
+#ifndef SEEK_END
+#define SEEK_END 2
+#endif
+
+
+#define misc_ERROROUT     stderr
+#define misc_USERERROROUT stderr
+
+typedef enum { FALSE=0, TRUE=1 } BOOL;
+
+#define misc_VERSION "V 2.1"
+
+
+typedef void*           POINTER;
+typedef unsigned int    NAT;
+
+/* Limits for EARL data types */
+#define NAT_MAX UINT_MAX
+
+
+/**************************************************************/
+/* Inline Functions                                           */
+/**************************************************************/
+
+#define misc_ReportStandardErrorMessage(Stream) fputs("\n Please report this error via email to spass@mpi-sb.mpg.de including\n the SPASS version, input problem, options, operating system.\n",Stream)
+
+static __inline__ void misc_Error(void)
+{
+  fflush(misc_USERERROROUT);
+  fflush(stdout);
+  fflush(stderr);
+  exit(EXIT_FAILURE);
+}
+
+
+static __inline__ void misc_DumpCore(void)
+{
+  fputs("\n\n", misc_ERROROUT);
+  fflush(misc_ERROROUT);
+  fflush(stdout);
+  fflush(stderr);
+  abort();
+}
+
+
+static __inline__ void misc_PrintChar(NAT Number, char Character)
+{
+  NAT Counter;
+  for (Counter = 1; Counter <= Number; Counter++)
+    putchar(Character);
+}
+
+static __inline__ BOOL misc_SmallerThan(int i, int j)
+{
+  return (BOOL)(i < j);
+}
+
+#define misc_StartErrorReport()  { fflush(stdout); fprintf(misc_ERROROUT,"\n\tError in file %s at line %d\n",__FILE__,__LINE__); }
+#define misc_FinishErrorReport() { misc_ReportStandardErrorMessage(misc_ERROROUT); misc_DumpCore(); }
+
+#define misc_StartUserErrorReport()    fflush(stdout)
+#define misc_FinishUserErrorReport()   misc_Error()
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define misc_ErrorReport(...) fprintf(misc_ERROROUT, __VA_ARGS__)
+#define misc_UserErrorReport(...) fprintf(misc_USERERROROUT, __VA_ARGS__)
+
+void  misc_DumpCoreOut(const char*);
+int   misc_ReturnValue(void);
+int   misc_Max(int, int);
+
+FILE* misc_OpenFile(const char*, const char*);
+void  misc_CloseFile(FILE*, const char*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/test/spass/options.c b/test/spass/options.c
new file mode 100644
index 0000000000000000000000000000000000000000..c9e84b5cc22a935c4ab66a9afd3e3329da3b47e9
--- /dev/null
+++ b/test/spass/options.c
@@ -0,0 +1,1889 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *               SPASS OPTIONS HANDLING                   * */
+/* *                                                        * */
+/* *  $Module:   OPTIONS                                    * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* $Revision: 35442 $                                        * */
+/* $State$                                            * */
+/* $Date: 2007-03-28 17:24:40 -0700 (Wed, 28 Mar 2007) $                             * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* $RCSfile$ */
+
+
+/***************************************************************
+
+		 COPYRIGHT NOTICE:
+
+                 This file contains code that               
+                 has been copied with minor modifications   
+                 from the 'getopt' module in the            
+                 GNU gcc library 2.0. The copyright for
+                 this code is claimed by
+		 
+		 Copyright 1991 Regents of the 
+		 University of California.
+		 All rights reserved.
+
+		 The copying and modification of the
+		 original code is in accordance 
+		 with the copyright conditions for the      
+                 GNU gcc library, which are listed below.           
+
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+    Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+    All advertising materials mentioning features or use of this software
+    must display the following acknowledgement:
+
+    This product includes software developed by the University of
+    California, Berkeley and its contributors.
+
+    Neither the name of the University nor the names of its contributors
+    may be used to endorse or promote products derived from this software
+    without specific prior written permission.
+
+    This software is provided by the regents and contributors ``as is'' and
+    any express or implied warranties, including, but not limited to, the
+    implied warranties of merchantability and fitness for a particular purpose
+    are disclaimed.  in no event shall the regents or contributors be liable
+    for any direct, indirect, incidental, special, exemplary, or consequential
+    damages (including, but not limited to, procurement of substitute goods
+    or services; loss of use, data, or profits; or business interruption)
+    however caused and on any theory of liability, whether in contract, strict
+    liability, or tort (including negligence or otherwise) arising in any way
+    out of the use of this software, even if advised of the possibility of
+    such damage.
+
+************************************************************************
+************************************************************************/
+
+#include "options.h"
+#include "stringsx.h"
+
+/**************************************************************/
+/* Local variables  and types                                 */
+/**************************************************************/
+
+/* all option declarations. List with *DECL entries */
+static LIST opts_DECLARATIONS;
+
+/* list of <option id/value string> tupels that holds all parameters and their values */
+static LIST opts_PARAMETERS;
+
+static OPTID opts_IdNextAvailable;
+
+
+/**************************************************************/
+/* Forwarding functions                                       */
+/**************************************************************/
+
+static void     opts_AddParam(OPTID, const char*);
+static BOOL     opts_AddParamCheck(OPTID, const char*);
+
+static int      opts_GetOptLongOnly(int, const char* [], const char*,
+				    const struct OPTION *, int *);
+
+static OPTDECL* opts_DeclGetById(OPTID);
+static void     opts_PrintDeclarationList(LIST);
+static OPTID    opts_IdNext(OPTID);
+static OPTID    opts_IdEqual(OPTID, OPTID);
+
+
+/*************************************************************
+  Local variables and types from the former getopt module code. 
+**************************************************************/
+
+/* 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 `opts_Ordering'.  In the case of RETURN_IN_ORDER, only
+   `--' can cause `getopt' to return -1 with `opts_Ind' != ARGC.  */
+
+static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } opts_Ordering;
+
+/* Value of POSIXLY_CORRECT environment variable.  */
+static char *opts_PosixlyCorrect;
+
+static int opts_FirstNonOpt;
+static int opts_LastNonOpt;
+
+/* Bash 2.0 gives us an environment variable containing flags
+   indicating ARGV elements that should not be considered arguments.  */
+
+static int opts_NonOptionFlagslen;
+
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `opts_Ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+static const char *opts_Arg = NULL;
+
+/* 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 -1, 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.  */
+
+/* 1003.2 says this must be 1 before any call.  */
+static int opts_Ind = 1;
+
+/* Formerly, initialization of getopt depended on opts_Ind==0, which
+   causes problems with re-calling getopt as programs generally don't
+   know that. */
+
+static int opts_GetOptInitialized = 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 const char *opts_NextChar;
+
+/* Callers store zero here to inhibit the error message
+   for unrecognized options.  */
+
+static int opts_Err = 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.  */
+
+static int opts_Opt = '?';
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+OPTID opts_IdFirst(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: First option id that is used in option declarations.
+***************************************************************/
+{
+  return opts_IDFIRST;
+}
+
+static __inline__ OPTID opts_IdNull(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: An NULL id that is never used for option declarations
+           (used as indicator for errors etc.).
+***************************************************************/
+{
+  return -1;
+}
+
+BOOL opts_IdIsNull(OPTID Id)
+/**************************************************************
+  INPUT:   An option id.
+  RETURNS: TRUE iff it is the NULL id. 
+***************************************************************/
+{
+  return opts_IdEqual(opts_IdNull(), Id);
+}
+
+static __inline__ void opts_IdIncAvailable(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: Nothing.
+  EFFECTS: Increases the counter for next available id.
+***************************************************************/
+{
+  opts_IdNextAvailable = opts_IdNext(opts_IdNextAvailable);
+}
+
+static __inline__ OPTID opts_IdGetNextAvailable(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: Nothing.
+  EFFECTS: Returns the counter for the next available id.
+***************************************************************/
+{
+  return opts_IdNextAvailable;
+}
+
+static __inline__ void opts_DeclSetClName(OPTDECL* D, char* s)
+/**************************************************************
+  INPUT:   An option declaration, a string.
+  RETURNS: Nothing.
+  EFFECTS: Sets the command line name of <D> to <s>.
+***************************************************************/
+{
+  D->clname = s;
+}
+
+static __inline__ char* opts_DeclGetClName(OPTDECL* D)
+/**************************************************************
+  INPUT:   An option declaration.
+  RETURNS: The command line name in <D>.
+***************************************************************/
+{
+  return D->clname;
+}
+
+
+static __inline__ void opts_DeclSetType(OPTDECL* D, OPTTYPE type)
+/**************************************************************
+  INPUT:   An option declaration and an option type.
+  RETURNS: Nothing.
+  EFFECTS: Set the option type of <D> to <type>.
+***************************************************************/
+{
+  D->type = type;
+}
+
+static __inline__ OPTTYPE opts_DeclGetType(OPTDECL* D)
+/**************************************************************
+  INPUT:   An option declaration.
+  RETURNS: The option type of <D>.
+***************************************************************/
+{
+  return D->type;
+}
+
+static __inline__ BOOL opts_DeclIsShortOpt(OPTDECL* D)
+/**************************************************************
+  INPUT:   An option declaration.
+  RETURNS: TRUE iff <D> is a declaration of a short option
+           (with a single character command line name).
+***************************************************************/
+{
+  return (strlen(opts_DeclGetClName(D)) == 1);
+}
+
+static __inline__ BOOL opts_DeclHasOptArg(OPTDECL* D) 
+/**************************************************************
+  INPUT:   An option declaration.
+  RETURNS: TRUE iff <D> is a declaration of an option
+           with an optional argument.
+***************************************************************/
+{
+  return (opts_DeclGetType(D) == opts_OPTARGTYPE);
+}
+
+static __inline__ BOOL opts_DeclHasReqArg(OPTDECL* D) 
+/**************************************************************
+  INPUT:   An option declaration.
+  RETURNS: TRUE iff <D> is a declaration of an option
+           with a required argument.
+***************************************************************/
+{
+  return (opts_DeclGetType(D) == opts_REQARGTYPE);
+}
+
+static __inline__ BOOL opts_DeclHasNoArg(OPTDECL* D) 
+/**************************************************************
+  INPUT:   An option declaration.
+  RETURNS: TRUE iff <D> is a declaration of an option
+           with a required argument.
+***************************************************************/
+{
+  return (opts_DeclGetType(D) == opts_NOARGTYPE );
+
+}
+
+OPTID opts_Declare(const char* ClName, OPTTYPE OptType)
+/* declare option by name/shorthand/argtype (command line name) */
+/**************************************************************
+  INPUT:   An option name (its command line name) and an option type.
+  RETURNS: An option id.
+  EFFECTS: Appends the declaration to opts_DECLARATIONS.
+***************************************************************/
+{
+  OPTDECL* D;
+  OPTID Id;
+
+  if (!opts_IdIsNull(opts_Id(ClName))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("internal error: option with command line name '%s' redeclared.\n", ClName);
+    misc_FinishErrorReport(); }
+
+  D  = memory_Malloc(sizeof(OPTDECL));
+
+  opts_DeclSetClName(D, string_StringCopy(ClName));
+  opts_DeclSetType(D,OptType);
+  
+  opts_DECLARATIONS = list_Nconc(opts_DECLARATIONS, list_List(D));
+
+  Id = opts_IdGetNextAvailable();
+  opts_IdIncAvailable();
+
+  return Id;
+}
+
+OPTID opts_DeclareVector(OPTDECL Decls[]) 
+/**************************************************************
+  INPUT:   An option declaration vector, which must have
+           a NULL pointer in the clname field of the last
+	   declaration.
+  RETURNS: The id of the last declared option.
+  EFFECTS: All option declarations are added to opts_DECLARATIONS.
+***************************************************************/
+{
+  int i;
+
+  i = 0;
+  while (strlen(opts_DeclGetClName(&Decls[i])) != 0) {
+    opts_Declare(opts_DeclGetClName(&Decls[i]), opts_DeclGetType(&Decls[i])); 
+    i++;
+  }
+  return opts_IdGetNextAvailable();
+}
+
+static char* opts_TranslateShortOptDeclarations(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: A string that codes the option declarations in
+           opts_DECLARATIONS in a string as required by the
+	   GNU getopt module.
+***************************************************************/
+{
+  LIST  Scan;
+  char* ShortDecl;
+  OPTDECL* Decl;
+
+  ShortDecl = string_StringCopy("\0");
+
+  Scan = opts_DECLARATIONS;
+  
+  while (Scan) {
+    /* option is short iff:
+         - it was declared with a one letter command line name or
+	 - it has an abbreviation
+	 */
+    Decl = (OPTDECL*)list_Car(Scan);
+    
+    if (opts_DeclIsShortOpt(Decl)) {
+      ShortDecl = string_Nconc(ShortDecl, string_StringCopy(opts_DeclGetClName(Decl)));      
+
+      /*
+	  add colon if optional or required argument 
+       */
+      if (opts_DeclHasReqArg(Decl)||opts_DeclHasOptArg(Decl)) 
+	ShortDecl = string_Nconc(ShortDecl, string_StringCopy(":"));
+    }
+    Scan = list_Cdr(Scan);
+  }
+
+  /* add leading colon if any short options exist */
+  if (strlen(ShortDecl) != 0) {
+    ShortDecl = string_Nconc(string_StringCopy(":"),ShortDecl); }
+
+  return ShortDecl;
+}
+
+static LIST opts_GetLongOptDeclarations(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: A list of all 'long option' (with command line name 
+           length > 1) declarations in opts_DECLARATIONS.
+  EFFECTS: Allocates list. 
+***************************************************************/
+{
+  LIST     Scan, Long;
+  OPTDECL* Decl;
+
+  Scan = opts_DECLARATIONS;
+  Long = list_Nil();
+
+  while (!list_Empty(Scan)) {
+    Decl = list_Car(Scan);
+
+    if (!opts_DeclIsShortOpt(Decl)) {
+      Long = list_Cons(Decl, Long);
+    }
+    Scan = list_Cdr(Scan);
+  }  
+  return Long;
+}
+
+static __inline__ struct OPTION *opts_GetLongOptsArray(int OptNum)
+/**************************************************************
+  INPUT:   An option number .
+  RETURNS: An array with <OptNum> entries for OPTION structs
+           as needed by GetOptLongOnly.
+  EFFECTS: Allocates array.
+***************************************************************/
+{
+  return (struct OPTION*)memory_Malloc(sizeof(struct OPTION)*(OptNum+1));
+}
+
+static void opts_FreeLongOptsArray(struct OPTION *LongOpts)
+/**************************************************************
+  INPUT:   An array with entries for OPTION structs
+  RETURNS: Nothing
+  EFFECTS: Frees array. End of array is marked by a struct OPTION
+           entry with a NULL pointer in the 'name' field.
+***************************************************************/
+{
+  int i;
+
+  for (i=0; LongOpts[i].name != 0; i++) /* empty */;
+
+  memory_Free(LongOpts, (i+1)*sizeof(struct OPTION));
+}
+
+
+static struct OPTION* opts_TranslateLongOptDeclarations(void)
+/**************************************************************
+  INPUT  : None
+  RETURNS: Translates opts_DECLARATIONS into an array as needed
+           by GetLongOptOnly
+  EFFECTS: Allocates the array
+***************************************************************/
+{
+  LIST           Scan;
+  LIST           LongDeclarations;
+  int            OptNum;
+  int            OptCnt;
+  struct OPTION* LongOpts;
+
+  OPTDECL* Decl;
+
+  LongDeclarations = opts_GetLongOptDeclarations();
+  OptNum           = list_Length(LongDeclarations);
+  LongOpts         = opts_GetLongOptsArray(OptNum);
+  OptCnt = 0;
+  Scan   = LongDeclarations;
+
+  while (!list_Empty(Scan)) {
+    Decl = list_Car(Scan);
+    
+    LongOpts[OptCnt].name = opts_DeclGetClName(Decl);
+
+    if (opts_DeclHasOptArg(Decl))
+      LongOpts[OptCnt].has_arg = 2;
+    else if (opts_DeclHasReqArg(Decl)) 
+      LongOpts[OptCnt].has_arg = 1; 
+    else 
+      LongOpts[OptCnt].has_arg = 0; 
+    LongOpts[OptCnt].flag    = 0;
+    LongOpts[OptCnt].val     = 0; 
+    
+    Scan = list_Cdr(Scan);
+    OptCnt++;
+  }
+  /* set last field to 0 as required by getopt */
+  LongOpts[OptCnt].name    = NULL;
+  LongOpts[OptCnt].has_arg = 0;
+  LongOpts[OptCnt].flag    = 0;
+  LongOpts[OptCnt].val     = 0;
+
+  list_Delete(LongDeclarations);
+
+  return LongOpts;
+}
+
+
+static void opts_PrintLongOpts(struct OPTION *LongOpts)
+/**************************************************************
+  INPUT:   An array with OPTIONS structs  
+  RETURNS: Nothing
+  EFFECTS: Prints contents of array
+***************************************************************/
+{
+  int i;
+
+  if (LongOpts == NULL) {
+    puts("\nPrintLongOpts gets NULL pointer.");
+    return;
+  }
+  puts("\nLong options array:");
+  
+  i = 0;
+  while (LongOpts[i].name != NULL) {
+    printf("\nentry %d:\n",i);
+
+    printf("Name:    %s\n", LongOpts[i].name);
+    printf("has_arg: %d\n", LongOpts[i].has_arg);
+    printf("flag;  : %d\n", (int)LongOpts[i].flag);
+    printf("val    : %d\n", LongOpts[i].val);
+    i++;
+  }
+}
+
+static __inline__ OPTID opts_IdCmp(OPTID Id1, OPTID Id2)
+/**************************************************************
+  INPUT:   Two option ids  
+  RETURNS: Analogously to strcmp: 
+              '0'   if Id1 == Id2
+	      '<0'  if Id1 <  Id2
+	      '>0'  if Id1 >  Id2
+***************************************************************/
+{
+  return (Id1-Id2);
+}
+
+static OPTID opts_IdEqual(OPTID Id1, OPTID Id2)
+/**************************************************************
+  INPUT:   Two options ids  
+  RETURNS: TRUE if they are equal
+***************************************************************/
+{
+  return (opts_IdCmp(Id1,Id2) == 0);
+}
+
+static OPTID opts_IdNext(OPTID Id)
+/**************************************************************
+  INPUT:   An option id  
+  RETURNS: The next option id in the ordering
+***************************************************************/
+{
+  return (Id+1);
+}
+
+
+const char* opts_ClName(OPTID Id)
+/**************************************************************
+  INPUT:   An option id
+  RETURNS: Its command line name
+***************************************************************/
+{
+  OPTDECL* Decl;
+
+  Decl = opts_DeclGetById(Id);
+  return opts_DeclGetClName(Decl);
+}
+
+OPTID opts_Id(const char* ClName) 
+/**************************************************************
+  INPUT:   The command line name of an option 
+  RETURNS: The corresponding id of the option,
+           the NULL id if no option with <ClName> exist.
+***************************************************************/
+{
+  LIST    Scan;
+  BOOL    found;
+  OPTID   Id;
+
+  Scan  = opts_DECLARATIONS;
+  Id    = opts_IdFirst();
+  found = FALSE;
+
+  while (!found && !list_Empty(Scan)) {
+    if (string_Equal(opts_DeclGetClName(list_Car(Scan)), ClName)) {
+      found = TRUE;
+    } else {
+      Scan = list_Cdr(Scan);
+      Id = opts_IdNext(Id);
+    }
+  }
+  if (!found)
+    Id = opts_IdNull();
+  return Id;
+}
+
+static OPTID opts_ShortOptId(char c)
+/**************************************************************
+  INPUT:   A character
+  RETURNS: The id of a short option <c>, NULL id
+           if it does not exist.
+***************************************************************/
+{
+  char Str[2];
+
+  Str[0] = c;
+  Str[1] = '\0';
+
+  return opts_Id(Str);
+}
+
+void opts_Init(void)
+/**************************************************************
+  INPUT:   None
+  RETURNS: Nothing 
+  EFFECT:  Initialize option module 
+***************************************************************/
+{
+  opts_DECLARATIONS = list_Nil();
+  opts_PARAMETERS   = list_Nil();
+  opts_Err = 1; /* let getopt generate its own error messages */
+  opts_IdNextAvailable = opts_IdFirst();
+}
+
+void opts_DeclareSPASSFlagsAsOptions(void)
+/**************************************************************
+  INPUT:   None
+  RETURNS: Nothing 
+  EFFECT:  Initialize option for use with SPASS: 
+           declares all SPASS flags as command line opts.
+  MEMORY:  Allocates space for declarations
+***************************************************************/
+{
+  int i;
+
+  for (i=0; i < flag_MAXFLAG; i++) {
+    opts_Declare(flag_Name(i), opts_OPTARGTYPE);
+  }
+}
+
+static void opts_FreeParameterPair(LIST Pair)
+/**************************************************************
+  INPUT  : An (id/string) pair
+  RETURNS: Nothing
+  EFFECTS: Frees memory of list element and string 
+***************************************************************/
+{
+  string_StringFree(list_PairSecond(Pair));
+
+  list_PairFree(Pair);
+}
+
+static void opts_FreeDecl(OPTDECL* D)
+/**************************************************************
+  INPUT:   An options declaration
+  RETURNS: Nothing
+  EFFECTS: Frees memory of struct. 
+***************************************************************/
+{
+  string_StringFree((char*)opts_DeclGetClName(D));
+  memory_Free(D, sizeof(OPTDECL));
+}
+
+void opts_Free(void)
+/**************************************************************
+  INPUT:   None
+  RETURNS: Nothing 
+  EFFECT:  Free memory of module
+***************************************************************/
+{
+  list_DeleteWithElement(opts_PARAMETERS, (void (*)(POINTER))opts_FreeParameterPair);
+  list_DeleteWithElement(opts_DECLARATIONS,(void (*)(POINTER))opts_FreeDecl);
+}
+
+static void opts_PrintDeclarationList(LIST Scan)
+/**************************************************************
+  INPUT:   A list with option declarations
+  RETURNS: Nothing
+  EFFECTS: Prints the list 
+***************************************************************/
+{
+  OPTDECL* Decl;
+  OPTID    Id;
+
+  Id = opts_IdFirst();
+
+  while (Scan) {
+    Decl = (OPTDECL*)list_Car(Scan);
+    printf("Id:%-6d Name:%-18s Type:%d\n", Id, opts_DeclGetClName(Decl),
+	   opts_DeclGetType(Decl));
+    Scan = list_Cdr(Scan);
+    Id   = opts_IdNext(Id);
+  }
+}
+
+static __inline__ void opts_PrintDeclarations(void)
+/**************************************************************
+  INPUT:   None
+  RETURNS: Nothing
+  EFFECTS: Prints all currently declared options 
+***************************************************************/
+{
+  opts_PrintDeclarationList(opts_DECLARATIONS);
+}
+
+static void opts_PrintParameters(void)
+/**************************************************************
+  INPUT:   None
+  RETURNS: Nothing
+  EFFECTS: Prints all values of options read so far 
+***************************************************************/
+{
+  LIST Scan;
+  LIST Pair;
+
+  Scan = opts_PARAMETERS;
+
+  while (!list_Empty(Scan)) {
+
+    Pair = list_Car(Scan);
+    printf("\nId: %d ", (OPTID)list_PairFirst(Pair));
+    printf("Par: %s", (char*) list_PairSecond(Pair));
+
+    Scan = list_Cdr(Scan);
+  }
+}
+
+
+void opts_PrintSPASSNames(void)
+/**************************************************************
+  INPUT:   None 
+  RETURNS: Nothing
+  EFFECT:  Prints all options in three rows
+***************************************************************/
+{
+  int i,j;
+  
+  for (i=0; i < flag_MAXFLAG; i=i+4) { 
+    for (j =0; j <=3; j++) {
+      if (i+j < flag_MAXFLAG)
+	printf("%-18s ", flag_Name(i+j)); } 
+    putchar('\n');
+  }
+}
+
+static OPTDECL* opts_DeclGetById(OPTID Id)
+/**************************************************************
+  INPUT  : An option id
+  RETURNS: The declaration corresponding to option <id>
+***************************************************************/
+{
+  OPTID ScanId;
+  LIST  Scan;
+
+  ScanId = opts_IdFirst();
+  Scan   = opts_DECLARATIONS;
+  
+  while (!list_Empty(Scan)) {
+    if (opts_IdEqual(Id, ScanId))
+      return list_Car(Scan);
+    Scan = list_Cdr(Scan);
+    ScanId = opts_IdNext(ScanId);
+  }
+
+  return (OPTDECL*)NULL;
+}
+
+
+/* Currently unused */
+/*static*/ OPTDECL* opts_DeclGetByClName(const char* ClName)
+/**************************************************************
+  INPUT  : A command line name
+  RETURNS: The declaration of the option with <ClName> as command
+           line name, NULL if there's no such option
+***************************************************************/
+{
+  OPTID Id;
+  
+  Id = opts_Id(ClName);
+  if (opts_IdIsNull(Id))
+    return NULL;
+  return opts_DeclGetById(Id);
+}
+
+
+BOOL opts_Read(int argc, const char* argv[])
+/**************************************************************
+  INPUT:   Program parameter data 
+  RETURNS: TRUE iff options are correctly specified 
+  EFFECT:  Errors are commented
+  MEMORY:  Builds up opts_PARAMETERS while reading
+           options and their values.
+***************************************************************/
+{
+  int        OptIndex, c;
+  char       *ShortOpts;
+  BOOL       Ok;
+  OPTID      OptId;
+  OPTDECL    *OptDecl;
+  const char *OptName;
+  struct OPTION *LongOpts;
+
+  Ok = TRUE;
+  
+  ShortOpts = opts_TranslateShortOptDeclarations();
+  LongOpts  = opts_TranslateLongOptDeclarations();
+
+  while (Ok && (c = opts_GetOptLongOnly(argc, argv, ShortOpts, 
+					LongOpts, &OptIndex)) != -1) {
+    /* 
+       for following eval of opts_GetOptLongOnly result see
+       GNU getopt documentation. In short, opts_GetOptLongOnly
+       returns a char if it has found that char as an option in
+       the command line, and this option is declared in opts_DECLARATIONS. 
+       It returns 0 if it has found a declared long option.
+       
+    */
+    if (c == '?') { 
+      /**** unknown option ****/ 
+
+      /* This has already been commented by opts_GetOptLongOnly */
+      return FALSE;
+    } else if (c == 0) {
+      /**** its a long option  ****/
+      
+      OptName = LongOpts[OptIndex].name;
+      OptId   = opts_Id(OptName);
+      OptDecl = opts_DeclGetById(OptId);
+      
+      if (opts_Arg == NULL) {
+	/* if argument required and no arg specified, error  */
+	if (opts_DeclHasReqArg(OptDecl)) {
+	  misc_StartUserErrorReport();
+	  misc_UserErrorReport("\nerror, option %s requires argument.\n", OptName);
+	  misc_FinishUserErrorReport();
+	  return FALSE;
+	}
+	
+	/* otherwise, set default value */
+	Ok = opts_AddParamCheck(OptId,opts_DEFAULTOPTARG);
+      } else  
+	Ok = opts_AddParamCheck(OptId,opts_Arg);
+    } else {
+      /**** its a short option ****/
+      
+      /* handle missing but required arguments. So far, this is left
+	 to opts_GetOptLongOnly */
+      if (c == ':') 
+	return FALSE;
+      
+      /* 
+	 
+	 One further special case: if a short option has an optional
+	 argument, but this argument is a '--', then take the
+	 default argument value. '--' normally signifies: no further
+	 options and is not interpreted nor returned by getopt as
+	 an argument value of an option with argument. As we
+	 permit default values for options with args, we have to declare
+	 all options with args. Therefore, getopt takes 
+	 
+	 -o -- 
+	 
+	 '-o with arg --' if "o:" is the declaration. We interpret
+	 this as '-o with default value'.
+	 
+      */
+      
+      else {
+	OptId = opts_ShortOptId(c);
+	if (opts_IdIsNull(OptId)) {
+	  misc_StartErrorReport();
+	  misc_ErrorReport("\ninternal error: option %c not found.\n", c);
+	  misc_FinishErrorReport();
+	}
+	OptDecl = opts_DeclGetById(OptId);
+	
+	if (opts_DeclHasReqArg(OptDecl)) {
+	  if (!opts_Arg) {
+	    misc_StartUserErrorReport();
+	    misc_UserErrorReport("\nerror: option %c requires argument.\n",c);
+	    misc_FinishUserErrorReport();
+	    Ok = FALSE;
+	  } else if (string_Equal(opts_Arg, opts_ENDMARKER)) {
+	    misc_StartUserErrorReport();
+	    misc_UserErrorReport("\nerror: option %c has delimiter -- as argument.\n",c);
+	    misc_FinishUserErrorReport();
+	    Ok = FALSE;
+	  } else 
+	    Ok = opts_AddParamCheck(OptId,opts_Arg);
+	}
+	/* options with args */
+	else if (opts_DeclHasOptArg(OptDecl)) {
+	  /* if arg is present, check for endmarker */
+	  if (opts_Arg) {
+	    if (string_Equal(opts_Arg, opts_ENDMARKER)) 
+	      Ok = opts_AddParamCheck(OptId,opts_DEFAULTOPTARG);
+	    else 
+	      Ok = opts_AddParamCheck(OptId,opts_Arg); }
+	  else 
+	    Ok = opts_AddParamCheck(OptId,opts_DEFAULTOPTARG);
+	}
+	/* default for options without args */
+	else 
+	  Ok = opts_AddParamCheck(OptId,opts_DEFAULTOPTARG);
+      }
+    }
+  }
+  
+  string_StringFree(ShortOpts);
+  opts_FreeLongOptsArray(LongOpts);
+  
+  return Ok;
+}
+
+
+BOOL opts_ReadOptionsFromString(const char* Options)
+/**************************************************************
+  INPUT:   A string containing program parameter data 
+  RETURNS: TRUE iff the string contains only valid options.
+           The function returns FALSE if the string contains
+	   any substring that isn't a option or invalid option
+	   settings.
+  EFFECT:  Errors are commented (via stderr).
+  MEMORY:  Builds up opts_PARAMETERS while reading options and
+           their values.
+  CAUTION: The function cannot !! be used in context with the
+           other option evaluation functions like opts_Read.
+***************************************************************/
+{
+  char **argv;
+  char *Copy;
+  int  argc, i;
+  BOOL Result;
+
+  /* Copy the options string since "string_Tokens" modifies it temporarily */
+  Copy = string_StringCopy(Options);
+  /* Split the string into substrings without whitespace.             */
+  /* Collect the substrings in an array similar to "argv" for main(). */
+  argv = string_Tokens(Copy, &argc);
+
+  /* Check whether all options are valid. */
+  Result = opts_Read(argc, (const char**)argv);
+  /* Check whether the string contains only option settings. */
+  if (opts_Indicator() < argc)
+    Result = FALSE;
+
+  /* Cleanup */
+  for (i = argc-1; i >= 0; i--)
+    string_StringFree(argv[i]);
+  memory_Free(argv, sizeof(char)*(argc+1));
+  string_StringFree(Copy);
+
+  return Result;
+}
+
+
+BOOL opts_GetValueByName(const char* Name, const char** Value)
+/**************************************************************
+  INPUT:   An option command line name, a string by ref.
+  RETURNS: TRUE if an option with this name exists
+           in opts_PARAMETERS (as set by opts_Read()),
+	   and the assigned value of this option in <Value>.
+	   FALSE otherwise
+  EFFECTS: <*Value> is changed 
+***************************************************************/
+{
+  LIST Scan;
+  LIST Pair;
+  BOOL found;
+
+  found = FALSE;
+  Pair  = list_Nil(); /* to quiet gcc */
+
+  for (Scan = opts_PARAMETERS;
+       (!found && !list_Empty(Scan)); Scan = list_Cdr(Scan)) {
+    Pair = list_Car(Scan);
+    if (string_Equal(Name, opts_ClName((OPTID)list_PairFirst(Pair))))
+      found = TRUE;
+  }
+
+  if (found) 
+    (*Value) = list_PairSecond(Pair); 
+
+  return found;
+}
+
+BOOL opts_GetValue(OPTID Id, const char** s) 
+/**************************************************************
+  INPUT:   An option id, a string by reference
+  RETURNS: TRUE if an option with this id exists
+           in opts_PARAMETERS (as set by opts_Read()),
+	   and the assigned value of this option in <Value>.
+	   FALSE otherwise
+  EFFECTS: <s*> is changed 
+***************************************************************/
+{
+  LIST Scan;
+  LIST Pair;
+  BOOL found;
+
+  Pair  = list_Nil();
+  found = FALSE;
+
+  for (Scan = opts_PARAMETERS;
+       (!found && !list_Empty(Scan)); Scan = list_Cdr(Scan)) {
+    Pair = list_Car(Scan);
+    if (opts_IdEqual(Id, (OPTID)list_PairFirst(Pair)))
+      found = TRUE;
+  }
+
+  if (found) 
+    (*s) = list_PairSecond(Pair);
+
+  return found;
+}
+
+
+BOOL opts_GetIntValueByName(const char* Name, int* Val)
+/**************************************************************
+  INPUT:   An options name, an integer by reference
+  RETURNS: TRUE 
+           if an option with <Name> exists
+           in opts_PARAMETERS (as set by opts_Read()) and 
+	   if its assigned value is an integer.
+	   The assigned value of this option is returned in <Val>.
+	   FALSE 
+	   otherwise
+  EFFECTS: <Val*> is changed 
+***************************************************************/
+{
+  const char* ValStr ;
+
+  if (!opts_GetValueByName(Name, &ValStr)) 
+    return FALSE;
+  
+  return string_StringToInt(ValStr, FALSE, Val);
+}
+
+BOOL opts_GetIntValue(OPTID Id, int* i) 
+/**************************************************************
+  INPUT:   An options name, an integer by reference
+  RETURNS: TRUE 
+           if an option with <Id> exists
+           in opts_PARAMETERS (as set by opts_Read()) and 
+	   if its assigned value is an integer.
+	   T he assigned value of this option is returned in <*i>.
+	   FALSE 
+           otherwise
+  EFFECTS: <*i> is changed 
+***************************************************************/
+{
+  return opts_GetIntValueByName(opts_ClName(Id), i);
+}
+
+
+
+BOOL opts_IsSet(OPTID Id)
+/**************************************************************
+  INPUT:   An option id
+  RETURNS: TRUE iff the option has been set in the command line
+           (that is, is listed in opts_PARAMETERS)
+***************************************************************/
+{
+  LIST Scan;
+  LIST Pair;
+  BOOL found;
+  
+  found = FALSE;
+
+  for (Scan = opts_PARAMETERS;
+       (!found && !list_Empty(Scan)); Scan = list_Cdr(Scan)) {
+    Pair = list_Car(Scan);
+    if (opts_IdEqual(Id, (OPTID)list_Car(Pair)))
+      found = TRUE;
+  }
+  return found;
+}
+
+
+/* Currently unused */
+/*static*/ BOOL opts_IsSetByName(const char* Name)
+/**************************************************************
+  INPUT:   An option name
+  RETURNS: TRUE iff option with this name has been set in command line
+***************************************************************/
+{
+  LIST Scan;
+  LIST Pair;
+  BOOL found;
+  
+  found = FALSE;
+
+  for (Scan = opts_PARAMETERS;
+       (!found && !list_Empty(Scan)); Scan = list_Cdr(Scan)) {
+    Pair = list_Car(Scan);
+    if (string_Equal(Name, opts_ClName((OPTID)list_PairFirst(Pair))))
+      found = TRUE;
+  }
+  return found;
+}
+
+void opts_SetFlags(FLAGSTORE Store)
+/**************************************************************
+  INPUT:   A flag store.
+  RETURNS: Nothing
+  EFFECT : Transfer options into SPASS flags in <Store>
+  CAUTION: To connect SPASS flags and options, we assume that
+           all flag names and command line names of all options
+	   are the same!
+***************************************************************/
+{
+  int     IntValue;
+  OPTID   Id;
+  FLAG_ID i;
+
+  for (i = 0; i < flag_MAXFLAG; i++) {
+    Id = opts_Id(flag_Name(i));
+    if (opts_IsSet(Id)) {
+      if (opts_GetIntValue(Id, &IntValue)) {
+	flag_SetFlagValue(Store, Id, IntValue);
+      } else {
+	misc_StartUserErrorReport();
+	misc_UserErrorReport("\nerror: argument of option %s must be integer.\n",flag_Name(i));
+	misc_FinishUserErrorReport();
+      }
+    }
+  }
+}
+
+void opts_Transfer(FLAGSTORE Store)
+/**************************************************************
+  INPUT:   A flag store.
+  RETURNS: Nothing
+  EFFECT:  Transfer options from 'opts_PARAMETERS' list into SPASS
+           flags in <Store> 
+  CAUTION: To connect SPASS flags and options, we assume that
+           all flag names and command line names of all options
+	   are the same!
+***************************************************************/
+{
+  LIST       Scan;
+  LIST       Pair;
+  int        IntValue;
+  const char *Name, *ValStr;
+  OPTID      Id;
+  BOOL       ok;
+
+  Scan = opts_PARAMETERS;
+
+  while (!list_Empty(Scan)) {
+    Pair    = list_Car(Scan);
+    Id      = (int)list_PairFirst(Pair);
+    ValStr  = (const char*)list_PairSecond(Pair);
+    Name    = opts_ClName(Id);
+    
+    ok = string_StringToInt(ValStr, FALSE, &IntValue);
+    if (!ok) {
+      misc_StartUserErrorReport();
+      misc_UserErrorReport("\nerror: argument '%s' of option '%s' must be integer.\n",
+			   ValStr, Name);
+      misc_FinishUserErrorReport();
+    } else { 
+      flag_SetFlagValue(Store, flag_Id(Name), IntValue);
+    }
+    Scan = list_Cdr(Scan);
+  }
+}
+
+
+static void opts_AddParam(OPTID Id, const char* ValueString)
+/**************************************************************
+  INPUT:   An option id and a string with its assigned value 
+  RETURNS: Nothing.
+  EFFECT:  Add (Id, ValueString) tupel to 'opts_PARAMETERS' list
+***************************************************************/
+{ 
+  LIST Pair;
+  Pair = list_PairCreate((POINTER)Id, string_StringCopy(ValueString));
+  opts_PARAMETERS = list_Cons(Pair, opts_PARAMETERS); 
+}
+
+
+static BOOL opts_AddParamCheck(OPTID Id, const char* ValueString)
+/**************************************************************
+  INPUT:   An option id and a string
+  RETURNS: TRUE iff option with <Id> has not been defined
+  EFFECTS: Adds (<Id>,<ValueString>) tupel to opts_PARAMETERS 
+***************************************************************/
+{
+  const char* Dummy;
+  if (opts_GetValue(Id, &Dummy)) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("error: option %s is multiply defined.\n", opts_ClName(Id));
+    misc_FinishUserErrorReport();
+    return FALSE;
+  }
+  opts_AddParam(Id, ValueString);
+  return TRUE;
+}
+
+
+int opts_Indicator(void) 
+/**************************************************************
+  INPUT:   None
+  RETURNS: Integer variable indicating position of next argument
+***************************************************************/
+{
+  return opts_Ind;
+}
+
+
+static void opts_Exchange (const char *argv[])
+/**************************************************************
+  INPUT:   Reference to string
+  RETURNS: Nothing
+  EFFECT:  See below
+***************************************************************/
+
+/* Exchange two adjacent subsequences of ARGV.
+   One subsequence is elements [opts_FirstNonOpt,opts_LastNonOpt)
+   which contains all the non-options that have been skipped so far.
+   The other is elements [opts_LastNonOpt,opts_Ind), which contains all
+   the options processed since those non-options were skipped.
+
+   `opts_FirstNonOpt' and `opts_LastNonOpt' are relocated so that they describe
+   the new indices of the non-options in ARGV after they are moved.  */
+{
+  int bottom = opts_FirstNonOpt;
+  int middle = opts_LastNonOpt;
+  int top = opts_Ind;
+  const char *tem;
+
+  /* Exchange the shorter segment with the far end of the longer segment.
+     That puts the shorter segment into the right place.
+     It leaves the longer segment in the right place overall,
+     but it consists of two parts that need to be swapped next.  */
+
+  while (top > middle && middle > bottom) {
+    if (top - middle > middle - bottom) {
+      /* Bottom segment is the short one.  */
+      int len = middle - bottom;
+      register int i;
+      
+      /* Swap it with the top part of the top segment.  */
+      for (i = 0; i < len; i++) {
+	tem = argv[bottom + i];
+	argv[bottom + i] = argv[top - (middle - bottom) + i];
+	argv[top - (middle - bottom) + i] = tem;
+      }
+      /* Exclude the moved bottom segment from further swapping.  */
+      top -= len;
+    }
+    else {
+      /* Top segment is the short one.  */
+      int len = top - middle;
+      register int i;
+      
+      /* Swap it with the bottom part of the bottom segment.  */
+      for (i = 0; i < len; i++) {
+	tem = argv[bottom + i];
+	argv[bottom + i] = argv[middle + i];
+	argv[middle + i] = tem;
+      }
+      /* Exclude the moved top segment from further swapping.  */
+      bottom += len;
+    }
+  }
+  
+  /* Update records for the slots the non-options now occupy.  */
+
+  opts_FirstNonOpt += (opts_Ind - opts_LastNonOpt);
+  opts_LastNonOpt = opts_Ind;
+}
+
+
+static const char *opts_GetOptInitialize (int argc, const char *const argv[],
+					  const char *optstring)
+/**************************************************************
+  INPUT:   The command line arguments ('argc', 'argv') and
+           a string describing options ('optstring')
+  RETURNS: a possibly modified 'optstring'
+  EFFECT:  Several static variables related to options
+           processing are influenced (see below).
+  MEMORY:  None
+***************************************************************/
+{
+  /* 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.  */
+
+  opts_FirstNonOpt = opts_LastNonOpt = opts_Ind = 1;
+
+  opts_NextChar = NULL;
+
+  opts_PosixlyCorrect = getenv ("POSIXLY_CORRECT");
+
+  /* Determine how to handle the ordering of options and nonoptions.  */
+
+  if (optstring[0] == '-') {
+    opts_Ordering = RETURN_IN_ORDER;
+    ++optstring;
+  }
+  else if (optstring[0] == '+') {
+    opts_Ordering = REQUIRE_ORDER;
+    ++optstring;
+  }
+  else if (opts_PosixlyCorrect != NULL)
+    opts_Ordering = REQUIRE_ORDER;
+  else
+    opts_Ordering = PERMUTE;
+  
+  opts_NonOptionFlagslen = 0;
+  
+  return optstring;
+}
+
+static int opts_GetOptInternal (int argc, const char* argv[],
+				const char *optstring,
+				const struct OPTION *longopts, int *longind,
+				int long_only)
+/**************************************************************
+  INPUT:   An array of pointers to arguments (strings),
+           and format information. See below for extensive
+	   description
+  RETURNS: -1 only if there are no more options, otherwise
+           a value identifying a read option. See below.
+  EFFECT:  Affects statics opts_Ind, opts_Arg, opts_Opt,
+           opts_NextChar and argument array. See below.
+  MEMORY:  See below. 
+***************************************************************/
+/* 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 `opts_Ind' and `opts_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 -1.
+   Then `opts_Ind' 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 '?' after printing an error message.  If you set `opts_Err' to
+   zero, the error message is suppressed but we still return '?'.
+
+   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 `opts_Arg'.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `opts_Arg', otherwise `opts_Arg' 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 0 if that option's
+   `flag' field is nonzero, the value of the option's `val' field
+   if the `flag' field is zero.
+
+   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 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.  */
+{
+  opts_Arg = NULL;
+
+  if (!opts_GetOptInitialized || opts_Ind == 0) {
+    optstring = opts_GetOptInitialize(argc, argv, optstring);
+    opts_Ind = 1;		/* Don't scan ARGV[0], the program name.  */
+    opts_GetOptInitialized = 1;
+  }
+  
+  /* Test whether ARGV[opts_Ind] points to a non-option argument.
+     Either it does not have option syntax, or there is an environment flag
+     from the shell indicating it is not an option.  The later information
+     is only used when the used in the GNU libc.  */
+
+
+  if (opts_NextChar == NULL || *opts_NextChar == '\0') {
+    /* Advance to the next ARGV-element.  */
+    
+    /* Give OPTS_FIRSTNONOPT & LAST_NONOPT rational values if OPTS_IND has been
+       moved back by the user (who may also have changed the arguments).  */
+    if (opts_LastNonOpt > opts_Ind)
+      opts_LastNonOpt = opts_Ind;
+    if (opts_FirstNonOpt > opts_Ind)
+      opts_FirstNonOpt = opts_Ind;
+    
+    if (opts_Ordering == PERMUTE) {
+      /* If we have just processed some options following some non-options,
+	 exchange them so that the options come first.  */
+      
+      if (opts_FirstNonOpt != opts_LastNonOpt && opts_LastNonOpt != opts_Ind)
+	opts_Exchange(argv);
+      else if (opts_LastNonOpt != opts_Ind)
+	opts_FirstNonOpt = opts_Ind;
+      
+      /* Skip any additional non-options
+	 and extend the range of non-options previously skipped.  */
+      
+      while (opts_Ind < argc &&  (argv[opts_Ind][0] != '-' || argv[opts_Ind][1] == '\0'))
+	opts_Ind++;
+      opts_LastNonOpt = opts_Ind;
+    }
+    
+    /* The 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 (opts_Ind != argc && !strcmp(argv[opts_Ind], "--")) {
+      opts_Ind++;
+      
+      if (opts_FirstNonOpt != opts_LastNonOpt && opts_LastNonOpt != opts_Ind)
+	opts_Exchange(argv);
+      else if (opts_FirstNonOpt == opts_LastNonOpt)
+	opts_FirstNonOpt = opts_Ind;
+      opts_LastNonOpt = argc;
+      
+      opts_Ind = argc;
+    }
+    
+    /* If we have done all the ARGV-elements, stop the scan
+       and back over any non-options that we skipped and permuted.  */
+    
+    if (opts_Ind == argc) {
+      /* Set the next-arg-index to point at the non-options
+	 that we previously skipped, so the caller will digest them.  */
+      if (opts_FirstNonOpt != opts_LastNonOpt)
+	opts_Ind = opts_FirstNonOpt;
+      return -1;
+    }
+    
+    /* 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[opts_Ind][0] != '-' || argv[opts_Ind][1] == '\0')) {
+      if (opts_Ordering == REQUIRE_ORDER)
+	return -1;
+      opts_Arg = argv[opts_Ind++];
+      return 1;
+    }
+    
+    /* We have found another option-ARGV-element.
+       Skip the initial punctuation.  */
+    
+    opts_NextChar = (argv[opts_Ind] + 1
+		     + (longopts != NULL && argv[opts_Ind][1] == '-'));
+  }
+  
+  /* Decode the current option-ARGV-element.  */
+  
+  /* Check whether the ARGV-element is a long option.
+     
+     If long_only and the ARGV-element has the form "-f", where f is
+     a valid short option, don't consider it an abbreviated form of
+     a long option that starts with f.  Otherwise there would be no
+     way to give the -f short option.
+     
+     On the other hand, if there's a long option "fubar" and
+     the ARGV-element is "-fu", do consider that an abbreviation of
+     the long option, just like "--fu", and not "-f" with arg "u".
+     
+     This distinction seems to be the most useful approach.  */
+  
+  if (longopts != NULL
+      && (argv[opts_Ind][1] == '-'
+	  || (long_only && (argv[opts_Ind][2] || !strchr(optstring, argv[opts_Ind][1]))))) {
+    const char *nameend;
+    const struct OPTION *p;
+    const struct OPTION *pfound = NULL;
+    int exact = 0;
+    int ambig = 0;
+    int indfound = -1;
+    int option_index;
+    
+    for (nameend = opts_NextChar; *nameend && *nameend != '='; nameend++)
+      /* Do nothing.  */ ;
+    
+    /* Test all long options for either exact match
+       or abbreviated matches.  */
+    for (p = longopts, option_index = 0; p->name; p++, option_index++)
+      if (!strncmp (p->name, opts_NextChar, nameend - opts_NextChar)) {
+	if ((unsigned int) (nameend - opts_NextChar)
+	    == (unsigned int) 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 or later nonexact match found.  */
+	  ambig = 1;
+      }
+    
+    if (ambig && !exact) {
+      if (opts_Err) {
+	misc_StartUserErrorReport();
+	misc_UserErrorReport("%s: option `%s' is ambiguous\n", argv[0], argv[opts_Ind]);
+	misc_FinishUserErrorReport();
+      }
+      opts_NextChar += strlen(opts_NextChar);
+      opts_Ind++;
+      opts_Opt = 0;
+      return '?';
+    }
+    
+    if (pfound != NULL) {
+      option_index = indfound;
+      opts_Ind++;
+      if (*nameend) {
+	/* Don't test has_arg with >, because some C compilers don't
+	   allow it to be used on enums.  */
+	if (pfound->has_arg)
+	  opts_Arg = nameend + 1;
+	else {
+	  if (opts_Err) {
+	    if (argv[opts_Ind - 1][1] == '-') {
+	      /* --option */
+	      misc_StartUserErrorReport();
+	      misc_UserErrorReport("%s: option `--%s' doesn't allow an argument\n",argv[0], pfound->name);
+	      misc_FinishUserErrorReport();
+	    }
+	    else {
+	      /* +option or -option */
+	      misc_StartUserErrorReport();
+	      misc_UserErrorReport("%s: option `%c%s' doesn't allow an argument\n",
+				   argv[0], argv[opts_Ind - 1][0], pfound->name);
+	      misc_FinishUserErrorReport();
+	    }
+	  }
+	  opts_NextChar += strlen(opts_NextChar);
+	  
+	  opts_Opt = pfound->val;
+	  return '?';
+	}
+      }
+      else if (pfound->has_arg == 1) {
+	if (opts_Ind < argc)
+	  opts_Arg = argv[opts_Ind++];
+	else {
+	  if (opts_Err) {
+	    misc_StartUserErrorReport();
+	    misc_UserErrorReport("%s: option `%s' requires an argument\n",
+				 argv[0], argv[opts_Ind - 1]);
+	    misc_FinishUserErrorReport();
+	  }
+	  opts_NextChar += strlen(opts_NextChar);
+	  opts_Opt = pfound->val;
+	  return optstring[0] == ':' ? ':' : '?';
+	}
+      }
+      opts_NextChar += strlen(opts_NextChar);
+      if (longind != NULL)
+	*longind = option_index;
+      if (pfound->flag) {
+	*(pfound->flag) = pfound->val;
+	return 0;
+      }
+      return pfound->val;
+    }
+    
+    /* Can't find it as a long option.  If this is not opts_GetOptLong_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[opts_Ind][1] == '-'
+	|| strchr(optstring, *opts_NextChar) == NULL) {
+      if (opts_Err) {
+	if (argv[opts_Ind][1] == '-') {
+	  /* --option */
+	  misc_StartUserErrorReport();
+	  misc_UserErrorReport("%s: unrecognized option `--%s'\n",argv[0], opts_NextChar);
+	  misc_FinishUserErrorReport();
+	}
+	else {
+	  /* +option or -option */
+	  misc_StartUserErrorReport();
+	  misc_UserErrorReport("%s: unrecognized option `%c%s'\n",
+			       argv[0], argv[opts_Ind][0], opts_NextChar);
+	  misc_FinishUserErrorReport();
+	}
+      }
+      opts_NextChar = "";
+      opts_Ind++;
+      opts_Opt = 0;
+      return '?';
+    }
+  }
+  
+  /* Look at and handle the next short option-character.  */
+  
+  {
+    char c = *opts_NextChar++;
+    char *temp = strchr(optstring, c);
+
+    /* Increment `opts_Ind' when we start to process its last character.  */
+    if (*opts_NextChar == '\0')
+      ++opts_Ind;
+
+    if (temp == NULL || c == ':') {
+      if (opts_Err) {
+	if (opts_PosixlyCorrect) {
+	  /* 1003.2 specifies the format of this message.  */
+	  misc_StartUserErrorReport();
+	  misc_UserErrorReport("%s: illegal option -- %c\n", argv[0], c);
+	  misc_FinishUserErrorReport();
+	}
+	else {
+	  misc_StartUserErrorReport();
+	  misc_UserErrorReport("%s: invalid option -- %c\n", argv[0], c);
+	  misc_FinishUserErrorReport();
+	}
+      }
+      opts_Opt = c;
+      return '?';
+    }
+    /* Convenience. Treat POSIX -W foo same as long option --foo */
+    if (temp[0] == 'W' && temp[1] == ';') {
+      const char *nameend;
+      const struct OPTION *p;
+      const struct OPTION *pfound = NULL;
+      int exact = 0;
+      int ambig = 0;
+      int indfound = 0;
+      int option_index;
+      
+      /* This is an option that requires an argument.  */
+      if (*opts_NextChar != '\0') {
+	opts_Arg = opts_NextChar;
+	/* If we end this ARGV-element by taking the rest as an arg,
+	   we must advance to the next element now.  */
+	opts_Ind++;
+      }
+      else if (opts_Ind == argc) {
+	if (opts_Err) {
+	  /* 1003.2 specifies the format of this message.  */
+	  misc_StartUserErrorReport();
+	  misc_UserErrorReport("%s: option requires an argument -- %c\n", argv[0], c);
+	  misc_FinishUserErrorReport();
+	}
+	opts_Opt = c;
+	if (optstring[0] == ':')
+	  c = ':';
+	else
+	  c = '?';
+	return c;
+      }
+      else
+	/* We already incremented `opts_Ind' once;
+	   increment it again when taking next ARGV-elt as argument.  */
+	opts_Arg = argv[opts_Ind++];
+      
+      /* opts_Arg is now the argument, see if it's in the
+	 table of longopts.  */
+      
+      for (opts_NextChar = nameend = opts_Arg; *nameend && *nameend != '='; nameend++)
+	/* Do nothing.  */ ;
+      
+      /* Test all long options for either exact match
+	 or abbreviated matches.  */
+      for (p = longopts, option_index = 0; p->name; p++, option_index++)
+	if (!strncmp (p->name, opts_NextChar, nameend - opts_NextChar)) {
+	  if ((unsigned int) (nameend - opts_NextChar) == 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 or later nonexact match found.  */
+	    ambig = 1;
+	}
+      if (ambig && !exact) {
+	if (opts_Err) {
+	  misc_StartUserErrorReport();
+	  misc_UserErrorReport("%s: option `-W %s' is ambiguous\n", argv[0], argv[opts_Ind]);
+	  misc_FinishUserErrorReport();
+	}
+	opts_NextChar += strlen(opts_NextChar);
+	opts_Ind++;
+	return '?';
+      }
+      if (pfound != NULL) {
+	option_index = indfound;
+	if (*nameend) {
+	  /* Don't test has_arg with >, because some C compilers don't
+	     allow it to be used on enums.  */
+	  if (pfound->has_arg)
+	    opts_Arg = nameend + 1;
+	  else {
+	    if (opts_Err) {
+	      misc_StartUserErrorReport();
+	      misc_UserErrorReport("%s: option `-W %s' doesn't allow an argument\n", argv[0], pfound->name);
+	      misc_FinishUserErrorReport();
+	    }
+	    
+	    opts_NextChar += strlen(opts_NextChar);
+	    return '?';
+	  }
+	}
+	else if (pfound->has_arg == 1) {
+	  if (opts_Ind < argc)
+	    opts_Arg = argv[opts_Ind++];
+	  else {
+	    if (opts_Err) {
+	      misc_StartUserErrorReport();
+	      misc_UserErrorReport("%s: option `%s' requires an argument\n", argv[0], argv[opts_Ind - 1]);
+	      misc_FinishUserErrorReport();
+	    }
+	    opts_NextChar += strlen(opts_NextChar);
+	    return optstring[0] == ':' ? ':' : '?';
+	  }
+	}
+	opts_NextChar += strlen(opts_NextChar);
+	if (longind != NULL)
+	  *longind = option_index;
+	if (pfound->flag) {
+	  *(pfound->flag) = pfound->val;
+	  return 0;
+	}
+	return pfound->val;
+      }
+      opts_NextChar = NULL;
+      return 'W';	/* Let the application handle it.   */
+    }
+    if (temp[1] == ':') {
+      if (temp[2] == ':') {
+	/* This is an option that accepts an argument optionally.  */
+	if (*opts_NextChar != '\0') {
+	  opts_Arg = opts_NextChar;
+	  opts_Ind++;
+	}
+	else
+	  opts_Arg = NULL;
+	opts_NextChar = NULL;
+      }
+      else {
+	/* This is an option that requires an argument.  */
+	if (*opts_NextChar != '\0') {
+	  opts_Arg = opts_NextChar;
+	  /* If we end this ARGV-element by taking the rest as an arg,
+	     we must advance to the next element now.  */
+	  opts_Ind++;
+	}
+	else if (opts_Ind == argc) {
+	  if (opts_Err) {
+	    /* 1003.2 specifies the format of this message.  */
+	    misc_StartUserErrorReport();
+	    misc_UserErrorReport(("%s: option requires an argument -- %c\n"), argv[0], c);
+	    misc_FinishUserErrorReport();
+	  }
+	  opts_Opt = c;
+	  if (optstring[0] == ':')
+	    c = ':';
+	  else
+	    c = '?';
+	}
+	else
+	  /* We already incremented `opts_Ind' once;
+	     increment it again when taking next ARGV-elt as argument.  */
+	  opts_Arg = argv[opts_Ind++];
+	opts_NextChar = NULL;
+      }
+    }
+    return c;
+  }
+}
+
+
+/* Like opts_GetOptLong, but '-' as well as '--' can indicate a long option.
+   If an option that starts with '-' (not '--') doesn't match a long option,
+   but does match a short option, it is parsed as a short option
+   instead.  */
+
+static int opts_GetOptLongOnly(int argc, const char* argv[], const char *options,
+			       const struct OPTION *long_options, int *opt_index)
+/**************************************************************
+  FUNCTIONALITY: See opts_GetOptInternal
+***************************************************************/
+{
+  return opts_GetOptInternal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+static void opts_Dummy(void)
+/**************************************************************
+  Assemble all unused functions to quiet gcc
+***************************************************************/
+{
+  if (FALSE) {
+    opts_PrintParameters();
+    opts_PrintDeclarations();
+    opts_DeclHasNoArg(NULL);
+    opts_PrintLongOpts((struct OPTION*)NULL);
+    opts_Dummy();
+  }
+}
diff --git a/test/spass/options.h b/test/spass/options.h
new file mode 100644
index 0000000000000000000000000000000000000000..f41da831f68885bbc2344e386b62328d8f5b656c
--- /dev/null
+++ b/test/spass/options.h
@@ -0,0 +1,127 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *              SPASS OPTIONS HANDLING                    * */
+/* *                                                        * */
+/* *  $Module:    OPTIONS                                   * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* $RCSfile$ */
+
+
+#ifndef _OPTIONS_
+#define _OPTIONS_
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "flags.h"
+#include "list.h"
+
+
+/**************************************************************/
+/* Data Structures and Constants                              */
+/**************************************************************/
+
+/* option type */
+typedef int OPTTYPE;
+
+#define	opts_NOARGTYPE		0 /* no argument       */
+#define opts_REQARGTYPE	        1 /* required argument */
+#define opts_OPTARGTYPE         2 /* optional argument */
+
+/* option id   */
+typedef int OPTID;
+#define opts_IDFIRST            0 /* option id to start with      */
+
+/* struct for declaration of options */
+typedef struct {
+  char*   clname;      /* option name in the command line        */
+  OPTTYPE type;        /* argument type: required, optional, non */
+} OPTDECL;
+
+#define opts_ENDMARKER "--"     /* double hyphen: marks end of all options */
+#define opts_DEFAULTOPTARG  "1" /* default value of options with optional arguments */
+
+/**************************************************************
+ from the getopt.h file 
+ **************************************************************/
+struct OPTION
+{
+  char *name;
+
+  /* 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 *flag;
+  int val;
+};
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+void        opts_Init(void);
+void        opts_Free(void);
+OPTID       opts_DeclareVector(OPTDECL []);
+OPTID       opts_Declare(const char*, OPTTYPE);
+BOOL        opts_Read(int, const char* []);
+BOOL        opts_ReadOptionsFromString(const char*);
+int         opts_Indicator(void);
+
+BOOL        opts_IsSet(OPTID);
+BOOL        opts_GetIntValueByName(const char*, int*);
+BOOL        opts_GetValueByName(const char*, const char**);
+BOOL        opts_GetValue(OPTID, const char**);
+BOOL        opts_GetIntValue(OPTID, int*) ;
+
+const char* opts_ClName(OPTID);
+OPTID       opts_IdFirst(void);
+OPTID       opts_Id(const char*);
+BOOL        opts_IdIsNull(OPTID);
+
+/* specials for SPASS */
+void        opts_Transfer(FLAGSTORE);
+void        opts_SetFlags(FLAGSTORE);
+void        opts_DeclareSPASSFlagsAsOptions(void);
+void        opts_PrintSPASSNames(void);
+
+#endif
diff --git a/test/spass/order.c b/test/spass/order.c
new file mode 100644
index 0000000000000000000000000000000000000000..48a1dd32f31f16330891b314b141ab74a614c12c
--- /dev/null
+++ b/test/spass/order.c
@@ -0,0 +1,516 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *         INTERFACE FOR ALL ORDERING IMPLEMENTATIONS     * */
+/* *                                                        * */
+/* *  $Module:   ORDER                                      * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1997, 1998, 1999, 2000, 2001            * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "flags.h"
+#include "order.h"
+#include "kbo.h"
+#include "rpos.h"
+#include "symbol.h"
+
+NAT        ord_VARCOUNT[symbol__MAXSTANDARDVAR][2];
+PRECEDENCE ord_PRECEDENCE;
+
+
+static ord_RESULT ord_CheckDomPred(TERM T1, TERM T2, PRECEDENCE P)
+/**************************************************************
+  INPUT:   Two terms and a precedence.
+  RETURNS: An ordering result with respect to a possible domination
+           of leading predicates in <T1> or <T2>.
+***************************************************************/
+{
+  if ((term_IsAtom(T1) && symbol_HasProperty(term_TopSymbol(T1), DOMPRED)) ||
+      (term_IsAtom(T2) && symbol_HasProperty(term_TopSymbol(T2), DOMPRED))) {
+    if (term_IsAtom(T1)) {
+      if (term_IsAtom(T2)) {
+	if (symbol_HasProperty(term_TopSymbol(T1), DOMPRED) && 
+	    (!symbol_HasProperty(term_TopSymbol(T2), DOMPRED) ||
+	     symbol_PrecedenceGreater(P,term_TopSymbol(T1),term_TopSymbol(T2))))
+	  return ord_GREATER_THAN;
+	if (!symbol_HasProperty(term_TopSymbol(T1), DOMPRED) ||
+	    term_TopSymbol(T1) != term_TopSymbol(T2))
+	  return ord_SMALLER_THAN;
+	/* If the top symbols are equal, do the normal comparison */
+      } else {
+	/* T1 is an atom, T2 is not, so T1 is greater */
+	return ord_GREATER_THAN;
+      }
+    } else {
+      /* T1 is not an atom, so T2 must be an atom */
+      return ord_SMALLER_THAN;
+    }
+  }
+  return ord_UNCOMPARABLE;
+}
+
+
+ord_RESULT ord_Compare(TERM T1, TERM T2, FLAGSTORE FlagStore, PRECEDENCE P)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+***************************************************************/
+{
+  ord_RESULT Aux;
+
+#ifdef CHECK
+  if (fol_IsEquality(T1) || fol_IsEquality(T2)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In ord_Compare:");
+    misc_ErrorReport("\n Illegal input. One input term is an equality.");
+    misc_FinishErrorReport();    
+  }
+#endif
+  
+  Aux = ord_CheckDomPred(T1, T2, P);
+  if (Aux != ord_UNCOMPARABLE)
+    return Aux;
+  else {
+    ord_PRECEDENCE = P;
+    switch(flag_GetFlagValue(FlagStore, flag_ORD)) {
+    case flag_ORDKBO:  return kbo_Compare(T1, T2); break;
+    case flag_ORDRPOS: return rpos_Compare(T1, T2); break;
+    default:
+      misc_StartErrorReport(); 
+      misc_ErrorReport("\n In ord_Compare:");
+      misc_ErrorReport("\n Illegal ordering type.");
+      misc_FinishErrorReport();
+    }
+  }
+  return ord_UNCOMPARABLE;
+}
+
+
+BOOL ord_CompareEqual(TERM T1, TERM T2, FLAGSTORE Flags)
+/**************************************************************
+  INPUT:   Two terms and a flag store.
+  RETURNS: TRUE, iff the two terms are equal with respect to the
+           reduction ordering selected by the 'flag_ORD' flag.
+***************************************************************/
+{
+  switch(flag_GetFlagValue(Flags, flag_ORD)) {
+  case flag_ORDKBO:  return term_Equal(T1, T2); break;
+  case flag_ORDRPOS: return rpos_Equal(T1, T2); break;
+  default:
+    misc_StartErrorReport(); 
+    misc_ErrorReport("\n In ord_Compare: Illegal ordering type.");
+    misc_FinishErrorReport();
+    return FALSE;   /* unreachable code ... */
+  }
+}
+
+ord_RESULT ord_ContCompare(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2,
+			   FLAGSTORE FlagStore, PRECEDENCE P)
+{
+  ord_RESULT Aux;
+
+#ifdef CHECK
+  if (fol_IsEquality(T1) || fol_IsEquality(T2)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In ord_ContCompare:");
+    misc_ErrorReport("\n Illegal input. One input term is an equality.");
+    misc_FinishErrorReport();
+  }
+#endif 
+  
+  Aux = ord_CheckDomPred(T1, T2, P);
+  if (Aux != ord_UNCOMPARABLE)
+    return Aux;
+  else {
+    ord_PRECEDENCE = P;
+    switch(flag_GetFlagValue(FlagStore, flag_ORD)) {
+    case flag_ORDKBO:  return kbo_ContCompare(C1, T1, C2, T2); break;
+    case flag_ORDRPOS: return rpos_ContCompare(C1, T1, C2, T2); break;
+    default:
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In ord_ContCompare:");
+      misc_ErrorReport("\n Illegal ordering type.");
+      misc_FinishErrorReport();
+    }
+  }
+  return ord_UNCOMPARABLE;
+}
+
+
+BOOL ord_ContGreater(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2,
+		     FLAGSTORE FlagStore, PRECEDENCE P)
+{ 
+  ord_RESULT Aux;
+
+#ifdef CHECK
+  if (fol_IsEquality(T1) || fol_IsEquality(T2)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In ord_ContGreater:");
+    misc_ErrorReport("\n Illegal input. One input term is an equality.");
+    misc_FinishErrorReport();
+  }
+#endif 
+  
+  Aux = ord_CheckDomPred(T1, T2, P);
+  if (Aux != ord_UNCOMPARABLE)
+    return (Aux == ord_GREATER_THAN);
+  else {
+    ord_PRECEDENCE = P;
+    switch(flag_GetFlagValue(FlagStore, flag_ORD)) {
+    case flag_ORDKBO:  return kbo_ContGreater(C1, T1, C2, T2); break;
+    case flag_ORDRPOS: return rpos_ContGreater(C1, T1, C2, T2); break;
+    default:
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In ord_ContGreater:");
+      misc_ErrorReport("\n Illegal ordering type.");
+      misc_FinishErrorReport();
+    }
+  }
+  return FALSE;   /* This line is never reached ...  */
+}
+
+
+ord_RESULT ord_Not(ord_RESULT Result)
+/**************************************************************
+  INPUT:   An ord_RESULT
+  RETURNS: The negation with respect to argument switching.
+***************************************************************/
+{
+  if (Result == ord_UNCOMPARABLE || Result == ord_EQUAL)
+    return Result;
+
+  if (Result == ord_GREATER_THAN)
+    return ord_SMALLER_THAN;
+
+  return ord_GREATER_THAN;
+}
+
+
+void ord_Print(ord_RESULT Result)
+/**************************************************************
+  INPUT:   An ord_Result.
+  RETURNS: None, prints the Result as a string to stdout.
+***************************************************************/
+{
+  switch(Result) { 
+  case ord_UNCOMPARABLE:  fputs(" uncomparable ",stdout); break;
+  case ord_EQUAL:         fputs(" equal ",stdout); break;
+  case ord_GREATER_THAN:  fputs(" greater than ",stdout); break;
+  case ord_SMALLER_THAN:  fputs(" smaller than ",stdout); break;
+  default:                fputs(" Nonsense! ",stdout);
+  }
+}
+
+
+ord_RESULT ord_LiteralCompare(TERM Lit1, BOOL Orient1, TERM Lit2, BOOL Orient2,
+			      BOOL Check, FLAGSTORE FlagStore,
+			      PRECEDENCE Precedence)
+/*********************************************************
+  INPUT:   Two term literals and two flags indicating whether these
+           two literals are oriented equalities. 
+	   Additionally a check flag that indicates whether
+	   the orientation flags are sufficient or necessary and sufficient:
+	   If Check=TRUE then if flag is FALSE it is interpreted that it is not
+	   known whether the (possible) equation can be oriented oriented.
+	   However, if flag is TRUE we assume that it is oriented.
+	   A flag store.
+	   A precedence.
+  RETURNS: The result if these literals are compared with
+           respect to the ordering. Dependent on their sign, the literals
+	   are compared as multiset of their topsymbol terms,
+	   where any literal is considered to be an equation
+	   and non equational literals are considered to be
+	   equations with the artificial, non-existent, minimal
+	   constant tt.
+  EFFECT:  The arguments of the literals are possibly, destructively flipped.
+**********************************************************/
+{
+  ord_RESULT result,auxResult,AuxRl1r2,AuxRr1r2,AuxRr1l2,Comp1,Comp2;
+  BOOL       pos1,pos2;
+
+  pos1  = pos2  = TRUE;
+  Comp1 = Comp2 = result = ord_UNCOMPARABLE;
+  if (symbol_Equal(term_TopSymbol(Lit1),fol_Not())) {
+    Lit1 = term_FirstArgument(Lit1);
+    pos1 = FALSE;
+  }
+  if (symbol_Equal(term_TopSymbol(Lit2),fol_Not())) {
+    Lit2 = term_FirstArgument(Lit2);
+    pos2 = FALSE;
+  }
+      
+  if (fol_IsEquality(Lit1)) {         /* Real equation */
+    if (fol_IsEquality(Lit2)) {
+      TERM       l1,r1,l2,r2,aux;
+      l1 = term_FirstArgument(Lit1);
+      r1 = term_SecondArgument(Lit1);
+      l2 = term_FirstArgument(Lit2);
+      r2 = term_SecondArgument(Lit2);
+      if (Orient1 || 
+	  (Check && 
+	   ((Comp1 = ord_Compare(l1,r1,FlagStore,Precedence)) == ord_GREATER_THAN ||
+	    Comp1 == ord_SMALLER_THAN))) {
+	if (Comp1 == ord_SMALLER_THAN) {
+	  aux = l1; l1 = r1; r1 = aux;
+	}
+	if (Orient2 ||
+	    (Check && 
+	     ((Comp2 = ord_Compare(l2,r2,FlagStore,Precedence))==ord_GREATER_THAN ||
+	      Comp2 == ord_SMALLER_THAN))) {
+	  /* Both equations are oriented */
+	  if (Comp2 == ord_SMALLER_THAN) {
+	    aux = l2; l2 = r2; r2 = aux;
+	  }
+	  result = ord_Compare(l1,l2, FlagStore, Precedence);
+	  if (result == ord_EQUAL) {
+	    if (pos1) {
+	      if (pos2)
+		return ord_Compare(r1,r2, FlagStore, Precedence);
+	      else
+		return ord_SMALLER_THAN;
+	    }
+	    else
+	      if (pos2)
+		return ord_GREATER_THAN;
+	      else
+		return ord_Compare(r1,r2, FlagStore, Precedence);
+	  }
+	  return result;
+	}
+	else { /* Lit2 is not oriented equation */
+	  if (term_Equal(l1,l2)) {
+	    result = ord_Compare(r1,r2, FlagStore, Precedence);
+	    if (result == ord_EQUAL) {
+	      if (pos1 && !pos2)
+		return ord_SMALLER_THAN;
+	      else
+		if (!pos1 && pos2)
+		  return ord_GREATER_THAN;
+	    }
+	    return result;
+	  }
+	  if (term_Equal(l1,r2)) {
+	    result = ord_Compare(r1,l2, FlagStore, Precedence);
+	    if (result == ord_EQUAL) {
+	      if (pos1 && !pos2)
+		return ord_SMALLER_THAN;
+	      else
+		if (!pos1 && pos2)
+		  return ord_GREATER_THAN;
+	    }
+	    return result;
+	  }
+	  result    = ord_Compare(l1,l2, FlagStore, Precedence);
+	  AuxRl1r2  = ord_Compare(l1,r2, FlagStore, Precedence);
+	  if (result == AuxRl1r2)
+	    return result;
+	  AuxRr1r2  = ord_Compare(r1,r2, FlagStore, Precedence);
+	  if (result == AuxRr1r2)
+	    return result;
+	  if (AuxRl1r2 == AuxRr1r2 && AuxRl1r2 == ord_SMALLER_THAN)
+	    return ord_SMALLER_THAN;
+	  AuxRr1l2  = ord_Compare(r1,l2, FlagStore, Precedence);
+	  if (result == AuxRr1l2 && result == ord_SMALLER_THAN)
+	    return  ord_SMALLER_THAN;	  
+	  return ord_UNCOMPARABLE;                   
+	}
+      }
+      else /* Lit1 is unorientable equation */
+	if (Orient2 ||
+	    (Check && 
+	     ((Comp2 = ord_Compare(term_FirstArgument(Lit2),
+				   term_SecondArgument(Lit2),
+				   FlagStore, Precedence) == ord_GREATER_THAN) ||
+	      Comp2 == ord_SMALLER_THAN))) {   /* Lit2 is orientable equation */
+	  if (Comp2 == ord_SMALLER_THAN) {
+	    aux = l2; l2 = r2; r2 = aux;
+	  }
+	  if (term_Equal(l1,l2)) {
+	    result = ord_Compare(r1,r2, FlagStore, Precedence);
+	    if (result == ord_EQUAL) {
+	      if (pos1 && !pos2)
+		return ord_SMALLER_THAN;
+	      else
+		if (!pos1 && pos2)
+		  return ord_GREATER_THAN;
+	    }
+	    return result;
+	  }
+	  if (term_Equal(r1,l2)) {
+	    result = ord_Compare(l1,r2, FlagStore, Precedence);
+	    if (result == ord_EQUAL) {
+	      if (pos1 && !pos2)
+		return ord_SMALLER_THAN;
+	      else
+		if (!pos1 && pos2)
+		  return ord_GREATER_THAN;
+	    }
+	    return result;
+	  }
+	  
+	  result    = ord_Compare(l1,l2, FlagStore, Precedence);
+	  AuxRr1l2  = ord_Compare(r1,l2, FlagStore, Precedence);
+	  if (result == AuxRr1l2)
+	    return result;
+	  AuxRr1r2  = ord_Compare(r1,r2, FlagStore, Precedence);
+	  if (result == AuxRr1r2)
+	    return result;
+	  if (AuxRr1l2 == AuxRr1r2 && AuxRr1l2 == ord_GREATER_THAN)
+	    return ord_GREATER_THAN;
+	  AuxRl1r2  = ord_Compare(l1,r2, FlagStore, Precedence);
+	  if (result == AuxRl1r2 && result == ord_GREATER_THAN)
+	    return  ord_GREATER_THAN;
+	  return ord_UNCOMPARABLE;
+	}
+	else { /* Both literals are unorientable equations */
+	  if (term_Equal(l1,l2)) {
+	    result = ord_Compare(r1,r2, FlagStore, Precedence);
+	    if (result == ord_EQUAL) {
+	      if (pos1 && !pos2)
+		return ord_SMALLER_THAN;
+	      else if (!pos1 && pos2)
+		return ord_GREATER_THAN;
+	    }
+	    return result;
+	  }
+	  if (term_Equal(r1,l2)) {
+	    result = ord_Compare(l1,r2, FlagStore, Precedence);
+	    if (result == ord_EQUAL) {
+	      if (pos1 && !pos2)
+		return ord_SMALLER_THAN;
+	      else if (!pos1 && pos2)
+		return ord_GREATER_THAN;
+	    }
+	    return result;
+	  }
+	  if (term_Equal(l1,r2)) {
+	    result = ord_Compare(r1,l2, FlagStore, Precedence); 
+	    if (result == ord_EQUAL) {
+	      if (pos1 && !pos2)
+		return ord_SMALLER_THAN;
+	      else if (!pos1 && pos2)
+		return ord_GREATER_THAN;
+	    }
+	    return result;
+	  }
+	  if (term_Equal(r1,r2)) {
+	    result = ord_Compare(l1,l2, FlagStore, Precedence);
+	    if (result == ord_EQUAL) {
+	      if (pos1 && !pos2)
+		return ord_SMALLER_THAN;
+	      else if (!pos1 && pos2)
+		return ord_GREATER_THAN;
+	    }
+	    return result;
+	  }
+	  result    = ord_Compare(l1,l2, FlagStore, Precedence);
+	  if (result == ord_UNCOMPARABLE) {
+	    result = ord_Compare(l1,r2, FlagStore, Precedence);
+	    if (result == ord_UNCOMPARABLE) {
+	     if (ord_Compare(r1,l2, FlagStore, Precedence) == ord_GREATER_THAN &&
+		 ord_Compare(r1,r2, FlagStore, Precedence) == ord_GREATER_THAN)
+	       return ord_GREATER_THAN;
+	     return ord_UNCOMPARABLE;
+	    }
+	    if (result == ord_GREATER_THAN) {
+	      if (ord_Compare(r1,l2, FlagStore, Precedence) == ord_GREATER_THAN)
+		return ord_GREATER_THAN;
+	      return ord_UNCOMPARABLE;
+	    }
+	    if (result == ord_SMALLER_THAN) {
+	      if (ord_Compare(r1,l2, FlagStore, Precedence) == ord_SMALLER_THAN ||
+		  ord_Compare(r1,r2, FlagStore, Precedence) == ord_SMALLER_THAN)
+		return ord_SMALLER_THAN;
+	      return ord_UNCOMPARABLE;
+	    }
+	  }
+	  if (result == ord_GREATER_THAN) {
+	    if ((result = ord_Compare(l1,r2,FlagStore,Precedence)) == ord_GREATER_THAN ||
+		(auxResult = ord_Compare(r1,r2,FlagStore,Precedence)) == ord_GREATER_THAN)
+	      return ord_GREATER_THAN;
+	    if (result == ord_UNCOMPARABLE || auxResult == ord_UNCOMPARABLE)
+		return ord_UNCOMPARABLE;
+	    return ord_SMALLER_THAN;
+	  }
+	  if (result == ord_SMALLER_THAN) {
+	    if ((result = ord_Compare(r1,l2,FlagStore,Precedence)) == ord_SMALLER_THAN ||
+		(auxResult = ord_Compare(r1,r2,FlagStore,Precedence)) == ord_SMALLER_THAN)
+	      return ord_SMALLER_THAN;
+	    if (result == ord_UNCOMPARABLE || auxResult == ord_UNCOMPARABLE)
+	      return ord_UNCOMPARABLE;
+	    return ord_GREATER_THAN;
+	  }
+	}
+    }
+    else {/* Second Atom is not an equation */
+      /* They can't be equal ! */
+      result = ord_Compare(term_FirstArgument(Lit1),Lit2,FlagStore,Precedence);
+      if (!Orient1 && result != ord_GREATER_THAN) { 
+	auxResult = ord_Compare(term_SecondArgument(Lit1),Lit2,FlagStore,Precedence);
+	if (auxResult == ord_GREATER_THAN)
+	  result = ord_GREATER_THAN;
+	else if (result != auxResult)
+	  result = ord_UNCOMPARABLE;
+      }
+    }
+  }
+  else /* First Atom is not an equation */
+    /* They can't be equal ! */
+    if (fol_IsEquality(Lit2)) {
+      result = ord_Compare(Lit1,term_FirstArgument(Lit2), FlagStore, Precedence);
+      if (!Orient2 && result != ord_SMALLER_THAN) { 
+	auxResult = ord_Compare(Lit1,term_SecondArgument(Lit2),FlagStore,Precedence);
+	if (auxResult == ord_SMALLER_THAN)
+	  result = ord_SMALLER_THAN;
+	else if (result != auxResult)
+	  result = ord_UNCOMPARABLE;
+      }
+    } else { /* None of the atoms is an equation */
+      result = ord_Compare(Lit1,Lit2, FlagStore, Precedence);
+      if (result == ord_EQUAL) {
+	if (pos1 && !pos2)
+	  result = ord_SMALLER_THAN;
+	else if (!pos1 && pos2)
+	  result = ord_GREATER_THAN;
+      }
+    }
+
+  return result;
+}
diff --git a/test/spass/order.h b/test/spass/order.h
new file mode 100644
index 0000000000000000000000000000000000000000..3817576fa721fbb07f58e3dd0dd0e0ecebf07d9d
--- /dev/null
+++ b/test/spass/order.h
@@ -0,0 +1,147 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *         INTERFACE FOR ALL ORDERING IMPLEMENTATIONS     * */
+/* *                                                        * */
+/* *  $Module:   ORDER                                      * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1997, 2000, 2001 MPI fuer Informatik    * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _ORDER_
+#define _ORDER_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "term.h"
+#include "context.h"
+#include "flags.h"
+#include "symbol.h"
+
+/**************************************************************/
+/* TYPES and GLOBAL VARIABLES                                 */
+/**************************************************************/
+
+typedef enum { ord_UNCOMPARABLE,
+	       ord_SMALLER_THAN,
+	       ord_EQUAL,
+	       ord_GREATER_THAN } ord_RESULT;
+
+/* This array is used to count variable occurrences in two terms. */
+/* It may be used by any available ordering.                     */
+extern NAT ord_VARCOUNT[symbol__MAXSTANDARDVAR][2];
+
+/* A precedence is needed in almost every ordering function. */
+/* For performance reasons it is stored in a global variable, */
+/* instead of passing it to all those functions, which are   */
+/* often recursive. Nevertheless this variable must not be   */
+/* set externally!                                           */
+extern PRECEDENCE ord_PRECEDENCE;
+
+/**************************************************************/
+/*  INLINE FUNCTIONS                                          */
+/**************************************************************/
+
+static __inline__ ord_RESULT ord_Uncomparable(void)
+{
+  return ord_UNCOMPARABLE;
+}
+
+static __inline__ ord_RESULT ord_Equal(void)
+{
+  return ord_EQUAL;
+}
+
+static __inline__ ord_RESULT ord_GreaterThan(void)
+{
+  return ord_GREATER_THAN;
+}
+
+static __inline__ ord_RESULT ord_SmallerThan(void)
+{
+  return ord_SMALLER_THAN;
+}
+
+static __inline__ BOOL ord_IsGreaterThan(ord_RESULT Res)
+{
+  return ord_GREATER_THAN == Res;
+}
+
+static __inline__ BOOL ord_IsNotGreaterThan(ord_RESULT Res)
+{
+  return ord_GREATER_THAN != Res;
+}
+
+static __inline__ BOOL ord_IsSmallerThan(ord_RESULT Res)
+{
+  return ord_SMALLER_THAN == Res;
+}
+
+static __inline__ BOOL ord_IsNotSmallerThan(ord_RESULT Res)
+{
+  return ord_SMALLER_THAN != Res;
+}
+
+static __inline__ BOOL ord_IsEqual(ord_RESULT Res)
+{
+  return ord_EQUAL == Res;
+}
+
+static __inline__ BOOL ord_IsUncomparable(ord_RESULT Res)
+{
+  return ord_UNCOMPARABLE == Res;
+}
+
+
+
+/**************************************************************/
+/*  FUNCTIONS                                                 */
+/**************************************************************/
+
+ord_RESULT ord_Not(ord_RESULT);
+ord_RESULT ord_Compare(TERM, TERM, FLAGSTORE, PRECEDENCE);
+ord_RESULT ord_ContCompare(CONTEXT, TERM, CONTEXT, TERM, FLAGSTORE, PRECEDENCE);
+BOOL       ord_CompareEqual(TERM, TERM, FLAGSTORE);
+BOOL       ord_ContGreater(CONTEXT, TERM, CONTEXT, TERM, FLAGSTORE, PRECEDENCE);
+ord_RESULT ord_LiteralCompare(TERM,BOOL,TERM,BOOL,BOOL, FLAGSTORE, PRECEDENCE);
+void       ord_Print(ord_RESULT);
+
+#endif
diff --git a/test/spass/partition.c b/test/spass/partition.c
new file mode 100644
index 0000000000000000000000000000000000000000..ac060da35be050401c23ffb9b5d91eb201b799b5
--- /dev/null
+++ b/test/spass/partition.c
@@ -0,0 +1,287 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *             PARTITION                                  * */
+/* *                                                        * */
+/* *  $Module:   PARTITION                                  * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1999, 2001 MPI fuer Informatik          * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                         * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/**************************************************************/
+/* Include                                                    */
+/**************************************************************/
+
+#include "partition.h"
+
+
+/**************************************************************/
+/* Inline functions                                           */
+/**************************************************************/
+
+static __inline__ ECLASS part_GetClass(PARTITION p, ELEMENT e)
+{
+  return p[e];
+}
+
+
+static __inline__ PARTITION part_SetClass(PARTITION p, ELEMENT e, ECLASS c)
+{
+  p[e] = c;
+  return p;
+}
+
+
+static __inline__ int part_GetClassSize(PARTITION p, ELEMENT e)
+{
+  return p[p[part_CARD] + e];
+}
+
+
+static __inline__ PARTITION part_SetClassSize(PARTITION p, ELEMENT e, int
+    classsize)
+{
+  p[p[part_CARD] + e] = classsize;
+  return p;
+}
+
+
+static __inline__ int part_GetStamp(PARTITION p, ELEMENT e)
+{
+  return p[-part_HEAD - 1 - e];
+}
+
+
+static __inline__ PARTITION part_SetStamp(PARTITION p, ELEMENT e, int stamp)
+{
+  p[-part_HEAD - 1 - e] = stamp;
+  return p;
+}
+
+
+static __inline__ BOOL part_Stamped(PARTITION p, ELEMENT e)
+{
+  return part_GetStamp(p, e) == p[part_STAMPCOUNTER];
+}
+
+
+static __inline__ ELEMENT part_DelayedInit(PARTITION p, ELEMENT e)
+/***************************************************************
+  RETURNS: the (now stamped) element
+  EFFECT:  establishes the equivalence class {e} in p, thus
+	   partially initializing p
+***************************************************************/
+{
+  if (!part_Stamped(p, e)) {
+    part_SetClass(p, e, -e - 1);  /* representative e (>= 0) of {e} is coded */
+				  /* as -e - 1 (< 0)                         */
+    part_SetClassSize(p, e, 1);
+    part_SetStamp(p, e, p[part_STAMPCOUNTER]);
+  }
+  return e;
+}
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+PARTITION part_Create(int size)
+/****************************************************************
+  RETURNS: the initial partition {{0}, {1}, {2}, ..., {size - 1}}
+	   of the set {0, 1, 2, ..., size - 1}
+****************************************************************/
+{
+  PARTITION result;
+
+#ifdef CHECK
+  if (size < 0) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In part_Create: negative size %d.", size);
+    misc_FinishErrorReport();
+  }
+#endif
+
+  result = (PARTITION) memory_Calloc(size * 3 + part_HEAD, sizeof(int))
+             + size + part_HEAD;  /* move pointer to the middle of the array */
+				  /* to allow negative indices               */
+  result[part_CARD]         = size;
+  result[part_ALLOC]        = size * 3 + part_HEAD;
+  result[part_STAMPCOUNTER] = 1;
+  return result;
+}
+
+
+PARTITION part_Init(PARTITION p, int size)
+/****************************************************************
+  RETURNS: the initial partition {{0}, {1}, {2}, ..., {size - 1}}
+           of the set {0, 1, 2, ..., size - 1}
+  EFFECT:  stores the initial partition to p if it's big enough,
+           otherwise creates a new partition, therefore
+  CAUTION: must be called inside an assignment like:
+             p = part_Init(p, ...)
+****************************************************************/
+{
+  int alloc, i;
+
+#ifdef CHECK
+  if (size < 0) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In part_Init: negative size %d.", size);
+    misc_FinishErrorReport();
+  }
+#endif
+
+  alloc = (p[part_ALLOC] - part_HEAD) / 3;
+  if (size > alloc) {
+    part_Free(p);
+    p = part_Create(size);
+  }
+  else {
+    p[part_CARD] = size;
+    p[part_STAMPCOUNTER]++;
+
+    /* if a stamp overflow occurs, reinit stamps: */
+    if (p[part_STAMPCOUNTER] <= 0) {
+      for (i = 0; i < alloc; i++)
+        part_SetStamp(p, i, 0);
+      p[part_STAMPCOUNTER] = 1;
+    }
+
+  }
+  return p;
+}
+
+
+static ELEMENT part_NF(PARTITION p, ELEMENT e)
+/***************************************************************
+  RETURNS: the normal form element of the class [e]; this is an 
+           element of [e] that sometimes differ from the
+           representative
+  EFFECT:  makes the normal form to the direct parent of all
+	   elements visited on the search path from e to this
+	   normal form ("path compression")
+***************************************************************/
+{
+  ELEMENT nf, aux;
+
+#ifdef CHECK
+  if (!part_Element(p, e)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In part_NF: %d not in partitioned set.", e);
+    misc_FinishErrorReport();
+  }
+#endif
+
+  nf = e;
+  while (part_GetClass(p, part_DelayedInit(p, nf)) >= 0)
+    nf = part_GetClass(p, nf);
+
+  /* path compression: */
+  while (e != nf) {
+    aux = part_GetClass(p, e);
+    part_SetClass(p, e, nf);
+    e = aux;
+  }
+
+  return nf;
+}
+
+
+ECLASS part_Find(PARTITION p, ELEMENT e)
+/***************************************************************
+  RETURNS: (the representative of) class [e]
+***************************************************************/
+{
+
+#ifdef CHECK
+  if (!part_Element(p, e)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In part_Find: %d not in partitioned set.", e);
+    misc_FinishErrorReport();
+  }
+#endif
+
+  return -part_GetClass(p, part_NF(p, e)) - 1;
+    /* representative e is coded as -e - 1 (cf. part_DelayedInit) */
+}
+
+
+PARTITION part_Union(PARTITION p, ECLASS c1, ECLASS c2)
+/***************************************************************
+  RETURNS: the union of the classes
+  EFFECT:  the representative of c1 is the representative of the
+           union
+***************************************************************/
+{
+  ELEMENT nf1, nf2, aux;
+
+#ifdef CHECK
+  if (!part_Element(p, c1)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In part_Union: first class %d not in partitioned set.",
+      c1);
+    misc_FinishErrorReport();
+  }
+  if (!part_Element(p, c2)) {
+    misc_StartErrorReport();
+    misc_ErrorReport
+      ("\n In part_Union: second class %d not in partitioned set.", c2);
+    misc_FinishErrorReport();
+  }
+#endif
+
+  nf1 = part_NF(p, c1);
+  nf2 = part_NF(p, c2);
+  if (nf1 != nf2) {
+
+    /* make [nf1] the bigger (or at least not smaller) class: */
+    if (part_GetClassSize(p, nf1) < part_GetClassSize(p, nf2)) {
+      aux = nf1;
+      nf1 = nf2;
+      nf2 = aux;
+      part_SetClass(p, nf1, part_GetClass(p, nf2));
+      part_SetClass(p, -part_GetClass(p, nf2) - 1, nf1);
+    }
+
+    part_SetClass(p, nf2, nf1);
+    part_SetClassSize(p, nf1,
+		      part_GetClassSize(p, nf1) + part_GetClassSize(p, nf2));
+  }
+  return p;
+}
+
diff --git a/test/spass/partition.h b/test/spass/partition.h
new file mode 100644
index 0000000000000000000000000000000000000000..2de3aad7b3777932227e3d99b148d282b85fbe77
--- /dev/null
+++ b/test/spass/partition.h
@@ -0,0 +1,127 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *             PARTITION                                  * */
+/* *                                                        * */
+/* *  $Module:   PARTITION                                  * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1999, 2000, 2001 MPI fuer Informatik    * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                         * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* module manages partitions (i. e. sets of equivalence classes) of the set */
+/* {0, 1, 2, ..., size - 1}                                                 */
+
+#ifndef _PARTITION_
+#define _PARTITION_
+
+
+/**************************************************************/
+/* Include                                                    */
+/**************************************************************/
+
+#include "memory.h"
+
+
+/**************************************************************/
+/* Constants and types                                        */
+/**************************************************************/
+
+#define part_CARD         -1  /* index of cardinality of partitioned set */
+#define part_ALLOC        -2  /* index of size of allocated space */
+#define part_STAMPCOUNTER -3  /* index of stampcounter */
+#define part_HEAD          3  /* length of head for management purposes */
+
+
+typedef int ELEMENT;
+typedef ELEMENT ECLASS, *PARTITION;
+
+/* an equivalence class is represented by one of its elements, the           */
+/* _representative_; a partition is an array to hold the size of the         */
+/* partitioned set and of the allocated space, the equivalence classes,      */
+/* their sizes and stamps and the stampcounter:                              */
+/*           STAMPCOUNTER ALLOC CARD                                         */
+/*                      |   |   |                                            */
+/* -size - 3, ..., -4, -3, -2, -1, 0, ..., size - 1, size, ..., 2 * size - 1 */
+/* <--- stamp[] ----|              |--- class[] -->  |---- classsize[] ----> */
+
+
+/**************************************************************/
+/* Prototypes                                                 */
+/**************************************************************/
+
+PARTITION part_Create(int);
+PARTITION part_Init(PARTITION, int);
+ECLASS part_Find(PARTITION, ELEMENT);
+  /* gets (the representative of) the class of the second argument */
+PARTITION part_Union(PARTITION, ECLASS, ECLASS);
+  /* unions the classes, the representative of the first class is the */
+  /* representative of the union                                      */
+
+
+/**************************************************************/
+/* Inline functions                                           */
+/**************************************************************/
+
+static __inline__ void part_Free(PARTITION p)
+{
+  if (p != NULL)
+    memory_Free(
+      p - (p[part_ALLOC] - part_HEAD) / 3 - part_HEAD,
+      p[part_ALLOC] * sizeof(int)
+    );
+}
+
+
+static __inline__ int part_Size(PARTITION p)
+{
+  return p[part_CARD];
+}
+
+
+static __inline__ BOOL part_Element(PARTITION p, ELEMENT e)
+{
+  return 0 <= e && e < part_Size(p);
+}
+
+
+static __inline__ BOOL part_Equivalent(PARTITION p, ELEMENT e1, ELEMENT e2)
+{
+  return part_Find(p, e1) == part_Find(p, e2);
+}
+
+
+#endif
+
diff --git a/test/spass/problem.dfg b/test/spass/problem.dfg
new file mode 100644
index 0000000000000000000000000000000000000000..4527e6aaa0f95e6f009dc52c51e4a1a8f1190889
--- /dev/null
+++ b/test/spass/problem.dfg
@@ -0,0 +1,718 @@
+%--------------------------------------------------------------------------
+% File     : SET505-6 : TPTP v2.2.1. Bugfixed v2.1.0.
+% Domain   : Set Theory
+% Problem  : Corollary 2 to universal class not set
+% Version  : [Qua92] axioms.
+% English  : 
+
+% Refs     : [BL+86] Boyer et al. (1986), Set Theory in First-Order Logic: 
+%          : [Qua92] Quaife (1992), Automated Deduction in von Neumann-Bern
+% Source   : [Quaife]
+% Names    : SP6 cor.2 [Qua92]
+
+% Status   : unsatisfiable
+% Rating   : 0.83 v2.2.0, 0.67 v2.1.0
+% Syntax   : Number of clauses    :  113 (   8 non-Horn;  38 unit;  80 RR)
+%            Number of literals   :  219 (  49 equality)
+%            Maximal clause size  :    5 (   1 average)
+%            Number of predicates :   11 (   0 propositional; 1-3 arity)
+%            Number of functors   :   47 (  13 constant; 0-3 arity)
+%            Number of variables  :  214 (  32 singleton)
+%            Maximal term depth   :    6 (   1 average)
+
+% Comments : Quaife proves all these problems by augmenting the axioms with 
+%            all previously proved theorems. With a few exceptions (the
+%            problems that correspond to [BL+86] problems), the TPTP has
+%            retained the order in which Quaife presents the problems. The
+%            user may create an augmented version of this problem by adding
+%            all previously proved theorems (the ones that correspond to
+%            [BL+86] are easily identified and positioned using Quaife's
+%            naming scheme).
+%          : tptp2X -f dfg -t rm_equality:rstfp SET505-6.p 
+% Bugfixes : v1.0.1 - Bugfix in SET004-1.ax.
+%          : v2.1.0 - Bugfix in SET004-0.ax.
+%--------------------------------------------------------------------------
+
+begin_problem(TPTP_Problem).
+
+list_of_descriptions.
+name({*[ File     : SET505-6 : TPTP v2.2.1. Bugfixed v2.1.0.],[ Names    : SP6 cor.2 [Qua92]]*}).
+author({*[ Source   : [Quaife]]*}).
+status(unsatisfiable).
+description({*[ Refs     : [BL+86] Boyer et al. (1986), Set Theory in First-Order Logic: ,          : [Qua92] Quaife (1992), Automated Deduction in von Neumann-Bern]*}).
+end_of_list.
+
+list_of_symbols.
+functions[(application_function,0), (apply,2), (cantor,1), (choice,0), (complement,1), (compose,2), (compose_class,1), (composition_function,0), (cross_product,2), (diagonalise,1), (domain,3), (domain_of,1), (domain_relation,0), (element_relation,0), (first,1), (flip,1), (identity_relation,0), (image,2), (intersection,2), (inverse,1), (not_homomorphism1,3), (not_homomorphism2,3), (not_subclass_element,2), (null_class,0), (omega,0), (ordered_pair,2), (power_class,1), (range,3), (range_of,1), (regular,1), (restrict,3), (rotate,1), (second,1), (single_valued1,1), (single_valued2,1), (single_valued3,1), (singleton,1), (singleton_relation,0), (subset_relation,0), (successor,1), (successor_relation,0), (sum_class,1), (symmetric_difference,2), (union,2), (universal_class,0), (unordered_pair,2), (y,0)].
+predicates[(compatible,3), (function,1), (homomorphism,3), (inductive,1), (maps,3), (member,2), (one_to_one,1), (operation,1), (single_valued_class,1), (subclass,2)].
+end_of_list.
+
+list_of_clauses(axioms,cnf).
+
+clause(
+forall([U,X,Y],
+or( not(subclass(X,Y)),
+    not(member(U,X)),
+    member(U,Y))),
+subclass_members ).
+
+clause(
+forall([X,Y],
+or( member(not_subclass_element(X,Y),X),
+    subclass(X,Y))),
+not_subclass_members1 ).
+
+clause(
+forall([X,Y],
+or( not(member(not_subclass_element(X,Y),Y)),
+    subclass(X,Y))),
+not_subclass_members2 ).
+
+clause(
+forall([X],
+or( subclass(X,universal_class))),
+class_elements_are_sets ).
+
+clause(
+forall([X,Y],
+or( not(equal(X,Y)),
+    subclass(X,Y))),
+equal_implies_subclass1 ).
+
+clause(
+forall([X,Y],
+or( not(equal(X,Y)),
+    subclass(Y,X))),
+equal_implies_subclass2 ).
+
+clause(
+forall([X,Y],
+or( not(subclass(X,Y)),
+    not(subclass(Y,X)),
+    equal(X,Y))),
+subclass_implies_equal ).
+
+clause(
+forall([U,X,Y],
+or( not(member(U,unordered_pair(X,Y))),
+    equal(U,X),
+    equal(U,Y))),
+unordered_pair_member ).
+
+clause(
+forall([X,Y],
+or( not(member(X,universal_class)),
+    member(X,unordered_pair(X,Y)))),
+unordered_pair2 ).
+
+clause(
+forall([X,Y],
+or( not(member(Y,universal_class)),
+    member(Y,unordered_pair(X,Y)))),
+unordered_pair3 ).
+
+clause(
+forall([X,Y],
+or( member(unordered_pair(X,Y),universal_class))),
+unordered_pairs_in_universal ).
+
+clause(
+forall([X],
+or( equal(unordered_pair(X,X),singleton(X)))),
+singleton_set ).
+
+clause(
+forall([X,Y],
+or( equal(unordered_pair(singleton(X),unordered_pair(X,singleton(Y))),ordered_pair(X,Y)))),
+ordered_pair ).
+
+clause(
+forall([U,V,X,Y],
+or( not(member(ordered_pair(U,V),cross_product(X,Y))),
+    member(U,X))),
+cartesian_product1 ).
+
+clause(
+forall([U,V,X,Y],
+or( not(member(ordered_pair(U,V),cross_product(X,Y))),
+    member(V,Y))),
+cartesian_product2 ).
+
+clause(
+forall([U,V,X,Y],
+or( not(member(U,X)),
+    not(member(V,Y)),
+    member(ordered_pair(U,V),cross_product(X,Y)))),
+cartesian_product3 ).
+
+clause(
+forall([X,Y,Z],
+or( not(member(Z,cross_product(X,Y))),
+    equal(ordered_pair(first(Z),second(Z)),Z))),
+cartesian_product4 ).
+
+clause(
+or( subclass(element_relation,cross_product(universal_class,universal_class))),
+element_relation1 ).
+
+clause(
+forall([X,Y],
+or( not(member(ordered_pair(X,Y),element_relation)),
+    member(X,Y))),
+element_relation2 ).
+
+clause(
+forall([X,Y],
+or( not(member(ordered_pair(X,Y),cross_product(universal_class,universal_class))),
+    not(member(X,Y)),
+    member(ordered_pair(X,Y),element_relation))),
+element_relation3 ).
+
+clause(
+forall([X,Y,Z],
+or( not(member(Z,intersection(X,Y))),
+    member(Z,X))),
+intersection1 ).
+
+clause(
+forall([X,Y,Z],
+or( not(member(Z,intersection(X,Y))),
+    member(Z,Y))),
+intersection2 ).
+
+clause(
+forall([X,Y,Z],
+or( not(member(Z,X)),
+    not(member(Z,Y)),
+    member(Z,intersection(X,Y)))),
+intersection3 ).
+
+clause(
+forall([X,Z],
+or( not(member(Z,complement(X))),
+    not(member(Z,X)))),
+complement1 ).
+
+clause(
+forall([X,Z],
+or( not(member(Z,universal_class)),
+    member(Z,complement(X)),
+    member(Z,X))),
+complement2 ).
+
+clause(
+forall([X,Y],
+or( equal(complement(intersection(complement(X),complement(Y))),union(X,Y)))),
+union ).
+
+clause(
+forall([X,Y],
+or( equal(intersection(complement(intersection(X,Y)),complement(intersection(complement(X),complement(Y)))),symmetric_difference(X,Y)))),
+symmetric_difference ).
+
+clause(
+forall([X,Xr,Y],
+or( equal(intersection(Xr,cross_product(X,Y)),restrict(Xr,X,Y)))),
+restriction1 ).
+
+clause(
+forall([X,Xr,Y],
+or( equal(intersection(cross_product(X,Y),Xr),restrict(Xr,X,Y)))),
+restriction2 ).
+
+clause(
+forall([X,Z],
+or( not(equal(restrict(X,singleton(Z),universal_class),null_class)),
+    not(member(Z,domain_of(X))))),
+domain1 ).
+
+clause(
+forall([X,Z],
+or( not(member(Z,universal_class)),
+    equal(restrict(X,singleton(Z),universal_class),null_class),
+    member(Z,domain_of(X)))),
+domain2 ).
+
+clause(
+forall([X],
+or( subclass(rotate(X),cross_product(cross_product(universal_class,universal_class),universal_class)))),
+rotate1 ).
+
+clause(
+forall([U,V,W,X],
+or( not(member(ordered_pair(ordered_pair(U,V),W),rotate(X))),
+    member(ordered_pair(ordered_pair(V,W),U),X))),
+rotate2 ).
+
+clause(
+forall([U,V,W,X],
+or( not(member(ordered_pair(ordered_pair(V,W),U),X)),
+    not(member(ordered_pair(ordered_pair(U,V),W),cross_product(cross_product(universal_class,universal_class),universal_class))),
+    member(ordered_pair(ordered_pair(U,V),W),rotate(X)))),
+rotate3 ).
+
+clause(
+forall([X],
+or( subclass(flip(X),cross_product(cross_product(universal_class,universal_class),universal_class)))),
+flip1 ).
+
+clause(
+forall([U,V,W,X],
+or( not(member(ordered_pair(ordered_pair(U,V),W),flip(X))),
+    member(ordered_pair(ordered_pair(V,U),W),X))),
+flip2 ).
+
+clause(
+forall([U,V,W,X],
+or( not(member(ordered_pair(ordered_pair(V,U),W),X)),
+    not(member(ordered_pair(ordered_pair(U,V),W),cross_product(cross_product(universal_class,universal_class),universal_class))),
+    member(ordered_pair(ordered_pair(U,V),W),flip(X)))),
+flip3 ).
+
+clause(
+forall([Y],
+or( equal(domain_of(flip(cross_product(Y,universal_class))),inverse(Y)))),
+inverse ).
+
+clause(
+forall([Z],
+or( equal(domain_of(inverse(Z)),range_of(Z)))),
+range_of ).
+
+clause(
+forall([X,Y,Z],
+or( equal(first(not_subclass_element(restrict(Z,X,singleton(Y)),null_class)),domain(Z,X,Y)))),
+domain ).
+
+clause(
+forall([X,Y,Z],
+or( equal(second(not_subclass_element(restrict(Z,singleton(X),Y),null_class)),range(Z,X,Y)))),
+range ).
+
+clause(
+forall([X,Xr],
+or( equal(range_of(restrict(Xr,X,universal_class)),image(Xr,X)))),
+image ).
+
+clause(
+forall([X],
+or( equal(union(X,singleton(X)),successor(X)))),
+successor ).
+
+clause(
+or( subclass(successor_relation,cross_product(universal_class,universal_class))),
+successor_relation1 ).
+
+clause(
+forall([X,Y],
+or( not(member(ordered_pair(X,Y),successor_relation)),
+    equal(successor(X),Y))),
+successor_relation2 ).
+
+clause(
+forall([X,Y],
+or( not(equal(successor(X),Y)),
+    not(member(ordered_pair(X,Y),cross_product(universal_class,universal_class))),
+    member(ordered_pair(X,Y),successor_relation))),
+successor_relation3 ).
+
+clause(
+forall([X],
+or( not(inductive(X)),
+    member(null_class,X))),
+inductive1 ).
+
+clause(
+forall([X],
+or( not(inductive(X)),
+    subclass(image(successor_relation,X),X))),
+inductive2 ).
+
+clause(
+forall([X],
+or( not(member(null_class,X)),
+    not(subclass(image(successor_relation,X),X)),
+    inductive(X))),
+inductive3 ).
+
+clause(
+or( inductive(omega)),
+omega_is_inductive1 ).
+
+clause(
+forall([Y],
+or( not(inductive(Y)),
+    subclass(omega,Y))),
+omega_is_inductive2 ).
+
+clause(
+or( member(omega,universal_class)),
+omega_in_universal ).
+
+clause(
+forall([X],
+or( equal(domain_of(restrict(element_relation,universal_class,X)),sum_class(X)))),
+sum_class_definition ).
+
+clause(
+forall([X],
+or( not(member(X,universal_class)),
+    member(sum_class(X),universal_class))),
+sum_class2 ).
+
+clause(
+forall([X],
+or( equal(complement(image(element_relation,complement(X))),power_class(X)))),
+power_class_definition ).
+
+clause(
+forall([U],
+or( not(member(U,universal_class)),
+    member(power_class(U),universal_class))),
+power_class2 ).
+
+clause(
+forall([Xr,Yr],
+or( subclass(compose(Yr,Xr),cross_product(universal_class,universal_class)))),
+compose1 ).
+
+clause(
+forall([Xr,Y,Yr,Z],
+or( not(member(ordered_pair(Y,Z),compose(Yr,Xr))),
+    member(Z,image(Yr,image(Xr,singleton(Y)))))),
+compose2 ).
+
+clause(
+forall([Xr,Y,Yr,Z],
+or( not(member(Z,image(Yr,image(Xr,singleton(Y))))),
+    not(member(ordered_pair(Y,Z),cross_product(universal_class,universal_class))),
+    member(ordered_pair(Y,Z),compose(Yr,Xr)))),
+compose3 ).
+
+clause(
+forall([X],
+or( not(single_valued_class(X)),
+    subclass(compose(X,inverse(X)),identity_relation))),
+single_valued_class1 ).
+
+clause(
+forall([X],
+or( not(subclass(compose(X,inverse(X)),identity_relation)),
+    single_valued_class(X))),
+single_valued_class2 ).
+
+clause(
+forall([Xf],
+or( not(function(Xf)),
+    subclass(Xf,cross_product(universal_class,universal_class)))),
+function1 ).
+
+clause(
+forall([Xf],
+or( not(function(Xf)),
+    subclass(compose(Xf,inverse(Xf)),identity_relation))),
+function2 ).
+
+clause(
+forall([Xf],
+or( not(subclass(Xf,cross_product(universal_class,universal_class))),
+    not(subclass(compose(Xf,inverse(Xf)),identity_relation)),
+    function(Xf))),
+function3 ).
+
+clause(
+forall([X,Xf],
+or( not(function(Xf)),
+    not(member(X,universal_class)),
+    member(image(Xf,X),universal_class))),
+replacement ).
+
+clause(
+forall([X],
+or( equal(X,null_class),
+    member(regular(X),X))),
+regularity1 ).
+
+clause(
+forall([X],
+or( equal(X,null_class),
+    equal(intersection(X,regular(X)),null_class))),
+regularity2 ).
+
+clause(
+forall([Xf,Y],
+or( equal(sum_class(image(Xf,singleton(Y))),apply(Xf,Y)))),
+apply ).
+
+clause(
+or( function(choice)),
+choice1 ).
+
+clause(
+forall([Y],
+or( not(member(Y,universal_class)),
+    equal(Y,null_class),
+    member(apply(choice,Y),Y))),
+choice2 ).
+
+clause(
+forall([Xf],
+or( not(one_to_one(Xf)),
+    function(Xf))),
+one_to_one1 ).
+
+clause(
+forall([Xf],
+or( not(one_to_one(Xf)),
+    function(inverse(Xf)))),
+one_to_one2 ).
+
+clause(
+forall([Xf],
+or( not(function(inverse(Xf))),
+    not(function(Xf)),
+    one_to_one(Xf))),
+one_to_one3 ).
+
+clause(
+or( equal(intersection(cross_product(universal_class,universal_class),intersection(cross_product(universal_class,universal_class),complement(compose(complement(element_relation),inverse(element_relation))))),subset_relation)),
+subset_relation ).
+
+clause(
+or( equal(intersection(inverse(subset_relation),subset_relation),identity_relation)),
+identity_relation ).
+
+clause(
+forall([Xr],
+or( equal(complement(domain_of(intersection(Xr,identity_relation))),diagonalise(Xr)))),
+diagonalisation ).
+
+clause(
+forall([X],
+or( equal(intersection(domain_of(X),diagonalise(compose(inverse(element_relation),X))),cantor(X)))),
+cantor_class ).
+
+clause(
+forall([Xf],
+or( not(operation(Xf)),
+    function(Xf))),
+operation1 ).
+
+clause(
+forall([Xf],
+or( not(operation(Xf)),
+    equal(cross_product(domain_of(domain_of(Xf)),domain_of(domain_of(Xf))),domain_of(Xf)))),
+operation2 ).
+
+clause(
+forall([Xf],
+or( not(operation(Xf)),
+    subclass(range_of(Xf),domain_of(domain_of(Xf))))),
+operation3 ).
+
+clause(
+forall([Xf],
+or( not(function(Xf)),
+    not(equal(cross_product(domain_of(domain_of(Xf)),domain_of(domain_of(Xf))),domain_of(Xf))),
+    not(subclass(range_of(Xf),domain_of(domain_of(Xf)))),
+    operation(Xf))),
+operation4 ).
+
+clause(
+forall([Xf1,Xf2,Xh],
+or( not(compatible(Xh,Xf1,Xf2)),
+    function(Xh))),
+compatible1 ).
+
+clause(
+forall([Xf1,Xf2,Xh],
+or( not(compatible(Xh,Xf1,Xf2)),
+    equal(domain_of(domain_of(Xf1)),domain_of(Xh)))),
+compatible2 ).
+
+clause(
+forall([Xf1,Xf2,Xh],
+or( not(compatible(Xh,Xf1,Xf2)),
+    subclass(range_of(Xh),domain_of(domain_of(Xf2))))),
+compatible3 ).
+
+clause(
+forall([Xf1,Xf2,Xh],
+or( not(function(Xh)),
+    not(equal(domain_of(domain_of(Xf1)),domain_of(Xh))),
+    not(subclass(range_of(Xh),domain_of(domain_of(Xf2)))),
+    compatible(Xh,Xf1,Xf2))),
+compatible4 ).
+
+clause(
+forall([Xf1,Xf2,Xh],
+or( not(homomorphism(Xh,Xf1,Xf2)),
+    operation(Xf1))),
+homomorphism1 ).
+
+clause(
+forall([Xf1,Xf2,Xh],
+or( not(homomorphism(Xh,Xf1,Xf2)),
+    operation(Xf2))),
+homomorphism2 ).
+
+clause(
+forall([Xf1,Xf2,Xh],
+or( not(homomorphism(Xh,Xf1,Xf2)),
+    compatible(Xh,Xf1,Xf2))),
+homomorphism3 ).
+
+clause(
+forall([X,Xf1,Xf2,Xh,Y],
+or( not(homomorphism(Xh,Xf1,Xf2)),
+    not(member(ordered_pair(X,Y),domain_of(Xf1))),
+    equal(apply(Xf2,ordered_pair(apply(Xh,X),apply(Xh,Y))),apply(Xh,apply(Xf1,ordered_pair(X,Y)))))),
+homomorphism4 ).
+
+clause(
+forall([Xf1,Xf2,Xh],
+or( not(operation(Xf1)),
+    not(operation(Xf2)),
+    not(compatible(Xh,Xf1,Xf2)),
+    member(ordered_pair(not_homomorphism1(Xh,Xf1,Xf2),not_homomorphism2(Xh,Xf1,Xf2)),domain_of(Xf1)),
+    homomorphism(Xh,Xf1,Xf2))),
+homomorphism5 ).
+
+clause(
+forall([Xf1,Xf2,Xh],
+or( not(operation(Xf1)),
+    not(operation(Xf2)),
+    not(compatible(Xh,Xf1,Xf2)),
+    not(equal(apply(Xf2,ordered_pair(apply(Xh,not_homomorphism1(Xh,Xf1,Xf2)),apply(Xh,not_homomorphism2(Xh,Xf1,Xf2)))),apply(Xh,apply(Xf1,ordered_pair(not_homomorphism1(Xh,Xf1,Xf2),not_homomorphism2(Xh,Xf1,Xf2)))))),
+    homomorphism(Xh,Xf1,Xf2))),
+homomorphism6 ).
+
+clause(
+forall([X],
+or( subclass(compose_class(X),cross_product(universal_class,universal_class)))),
+compose_class_definition1 ).
+
+clause(
+forall([X,Y,Z],
+or( not(member(ordered_pair(Y,Z),compose_class(X))),
+    equal(compose(X,Y),Z))),
+compose_class_definition2 ).
+
+clause(
+forall([X,Y,Z],
+or( not(member(ordered_pair(Y,Z),cross_product(universal_class,universal_class))),
+    not(equal(compose(X,Y),Z)),
+    member(ordered_pair(Y,Z),compose_class(X)))),
+compose_class_definition3 ).
+
+clause(
+or( subclass(composition_function,cross_product(universal_class,cross_product(universal_class,universal_class)))),
+definition_of_composition_function1 ).
+
+clause(
+forall([X,Y,Z],
+or( not(member(ordered_pair(X,ordered_pair(Y,Z)),composition_function)),
+    equal(compose(X,Y),Z))),
+definition_of_composition_function2 ).
+
+clause(
+forall([X,Y],
+or( not(member(ordered_pair(X,Y),cross_product(universal_class,universal_class))),
+    member(ordered_pair(X,ordered_pair(Y,compose(X,Y))),composition_function))),
+definition_of_composition_function3 ).
+
+clause(
+or( subclass(domain_relation,cross_product(universal_class,universal_class))),
+definition_of_domain_relation1 ).
+
+clause(
+forall([X,Y],
+or( not(member(ordered_pair(X,Y),domain_relation)),
+    equal(domain_of(X),Y))),
+definition_of_domain_relation2 ).
+
+clause(
+forall([X],
+or( not(member(X,universal_class)),
+    member(ordered_pair(X,domain_of(X)),domain_relation))),
+definition_of_domain_relation3 ).
+
+clause(
+forall([X],
+or( equal(first(not_subclass_element(compose(X,inverse(X)),identity_relation)),single_valued1(X)))),
+single_valued_term_defn1 ).
+
+clause(
+forall([X],
+or( equal(second(not_subclass_element(compose(X,inverse(X)),identity_relation)),single_valued2(X)))),
+single_valued_term_defn2 ).
+
+clause(
+forall([X],
+or( equal(domain(X,image(inverse(X),singleton(single_valued1(X))),single_valued2(X)),single_valued3(X)))),
+single_valued_term_defn3 ).
+
+clause(
+or( equal(intersection(complement(compose(element_relation,complement(identity_relation))),element_relation),singleton_relation)),
+compose_can_define_singleton ).
+
+clause(
+or( subclass(application_function,cross_product(universal_class,cross_product(universal_class,universal_class)))),
+application_function_defn1 ).
+
+clause(
+forall([X,Y,Z],
+or( not(member(ordered_pair(X,ordered_pair(Y,Z)),application_function)),
+    member(Y,domain_of(X)))),
+application_function_defn2 ).
+
+clause(
+forall([X,Y,Z],
+or( not(member(ordered_pair(X,ordered_pair(Y,Z)),application_function)),
+    equal(apply(X,Y),Z))),
+application_function_defn3 ).
+
+clause(
+forall([X,Y,Z],
+or( not(member(ordered_pair(X,ordered_pair(Y,Z)),cross_product(universal_class,cross_product(universal_class,universal_class)))),
+    not(member(Y,domain_of(X))),
+    member(ordered_pair(X,ordered_pair(Y,apply(X,Y))),application_function))),
+application_function_defn4 ).
+
+clause(
+forall([X,Xf,Y],
+or( not(maps(Xf,X,Y)),
+    function(Xf))),
+maps1 ).
+
+clause(
+forall([X,Xf,Y],
+or( not(maps(Xf,X,Y)),
+    equal(domain_of(Xf),X))),
+maps2 ).
+
+clause(
+forall([X,Xf,Y],
+or( not(maps(Xf,X,Y)),
+    subclass(range_of(Xf),Y))),
+maps3 ).
+
+clause(
+forall([Xf,Y],
+or( not(function(Xf)),
+    not(subclass(range_of(Xf),Y)),
+    maps(Xf,domain_of(Xf),Y))),
+maps4 ).
+
+end_of_list.
+
+list_of_clauses(conjectures,cnf).
+
+clause(  %(conjecture)
+or( member(ordered_pair(universal_class,y),cross_product(universal_class,universal_class))),
+prove_corollary_2_to_universal_class_not_set_1 ).
+
+end_of_list.
+
+end_problem.
+%--------------------------------------------------------------------------
diff --git a/test/spass/proofcheck.c b/test/spass/proofcheck.c
new file mode 100644
index 0000000000000000000000000000000000000000..15010d931ed36cc7287c37f00859d7e1b4ae6540
--- /dev/null
+++ b/test/spass/proofcheck.c
@@ -0,0 +1,1391 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *             PROOF CHECKING                             * */
+/* *                                                        * */
+/* *  Copyright (C) 1998, 1999, 2000, 2001                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+
+/* $RCSfile$ */
+
+#include "proofcheck.h"
+
+
+/* options */
+int        pcheck_Timelimit;
+const char *pcheck_ProofFileSuffix;
+BOOL       pcheck_Quiet;
+
+/* options for graph generation */
+BOOL        pcheck_ClauseCg;
+BOOL        pcheck_GenNamedCg, pcheck_GenRedCg;
+const char  *pcheck_CgName, *pcheck_RedCgName;
+GRAPHFORMAT pcheck_GraphFormat;
+
+
+static int pcheck_MaxSplitLevel(LIST Clauses)
+/**************************************************************
+  INPUT:   A list of clauses.
+  RETURNS: The maximum split level of a clause.
+***************************************************************/
+{
+  int Max;
+  int Act;
+  
+  Max = 0;
+  while (!list_Empty(Clauses)) {
+    Act = clause_SplitLevel(list_Car(Clauses));
+    if (Act > Max) 
+      Max = Act;
+    Clauses = list_Cdr(Clauses);
+  }
+  return Max;
+}
+
+
+static __inline__ int pcheck_MaxParentSplitLevel(CLAUSE Clause) 
+/**************************************************************
+  INPUT:   A clause
+  RETURNS: The max split level of the parent clauses
+***************************************************************/
+{
+  return pcheck_MaxSplitLevel(clause_ParentClauses(Clause));
+}
+
+
+static BOOL pcheck_ClauseIsFromLeftSplit(CLAUSE Clause)
+/**************************************************************
+  INPUT  : A Clause                                                      
+  RETURNS: TRUE iff the clause is the left half of a split
+  CAUTION: This works also for clauses without parents, since
+           pcheck_MaxParentSplitLevel returns 0 in that case.
+***************************************************************/
+{
+  return (clause_SplitLevel(Clause) > pcheck_MaxParentSplitLevel(Clause));
+}
+
+
+static BOOL pcheck_ClauseIsFromRightSplit(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A clause
+  RETURNS: TRUE iff the clause is from the right half of a split
+***************************************************************/
+{
+  if (list_Empty(clause_ParentClauses(Clause)))
+    return FALSE;
+
+  return clause_IsEmptyClause(list_Car(clause_ParentClauses(Clause)));
+}
+
+static BOOL pcheck_ClauseIsFromSplit(CLAUSE Clause)
+/**************************************************************
+ INPUT  : A clause
+ RETURNS: TRUE iff the clause is from a split
+***************************************************************/
+{
+  return (pcheck_ClauseIsFromRightSplit(Clause) ||
+	  pcheck_ClauseIsFromLeftSplit(Clause));
+}
+
+
+static int pcheck_LabelToNumber(const char* Label)
+/**************************************************************
+  INPUT:   A clause label
+  RETURNS: The label converted to a number.
+  EFFECT:  If the conversion fails an error message is printed
+           and the program exits.
+***************************************************************/
+{
+  int Number;
+
+  if (!string_StringToInt(Label, FALSE, &Number)) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n In pcheck_LabelToNumber:");
+    misc_UserErrorReport(" Could not convert clause");
+    misc_UserErrorReport(" label %s to a number.\n", Label);
+    misc_FinishUserErrorReport();
+  }
+
+  return Number;
+}
+
+
+static int pcheck_CompareNumberAndClause(const void* Number, const void* ClausePtr)
+/**************************************************************
+  INPUT:   A number and a pointer to a CLAUSE.
+  RETURNS: 1) a negative number if <number> is < number of <Clause>
+           2) 0 if <Number> is equal to the number of <Clause>
+           3) a positive number if <Number> is > number of <Clause>
+  EFFECT:  This function is used as parameter to the bsearch function.
+***************************************************************/
+{
+  return (int)Number - clause_Number(*(const CLAUSE*)ClausePtr);
+}
+
+
+static void pcheck_ParentNumbersToPointersInVector(CLAUSE* ClauseVector, int Size)
+/**************************************************************
+  INPUT:   A clause vector without duplicate clauses and the maximal
+           number of elements in the vector
+  EFFECTS: All clause parent numbers are replaced by pointers
+           to the parents.
+  CAUTION: The clause vector has to be sorted by increasing
+           clause numbers, since this function performs a binary search
+           on the vector.
+***************************************************************/
+{
+  int     Position;
+  LIST    NewParents, OldParents;
+  LIST    ScanParents;
+  int     ParentNum;
+  CLAUSE* Parent;
+  
+  for (Position = 0; Position < Size; Position++)  {
+    OldParents = clause_ParentClauses(ClauseVector[Position]);
+    NewParents = list_Copy(OldParents);
+    
+    for (ScanParents = NewParents; !list_Empty(ScanParents); ScanParents = list_Cdr(ScanParents)) {     
+      ParentNum = (int)list_Car(ScanParents);
+      /* Binary search for parent clause with number <ParentNum>. */
+      Parent = bsearch((const void*)ParentNum, ClauseVector, Size,
+		       sizeof(CLAUSE), pcheck_CompareNumberAndClause);
+      if (Parent != NULL)
+	list_Rplaca(ScanParents, *Parent);  
+      else {
+	misc_StartUserErrorReport();
+	misc_UserErrorReport("\n Error: Missing parent clause %d of clause %d.\n", 
+			     ParentNum, clause_Number(ClauseVector[Position]));
+	misc_FinishUserErrorReport();
+      }
+    }    
+    clause_SetParentClauses(ClauseVector[Position], NewParents);
+    list_Delete(OldParents); 
+  }
+}
+
+
+static LIST pcheck_ForceParentNumbersToPointersInVector(CLAUSE* ClauseVector,
+							int Size)
+/**************************************************************
+  INPUT:   A clause vector, possibly with duplicates
+  RETURNS: All numbers of clauses <c> that are missing a parent clause
+           from the transitive hull of parent clauses of <c>.
+  EFFECTS: All MARKED and HIDDEN flags of the clauses are changed.
+           All parent numbers are converted to pointers, if the
+           parents exist, otherwise the parent number is deleted
+           from the list.
+           The parent literal list is changed accordingly.
+           A clause <c> is marked as HIDDEN, if any clause
+           from the transitive hull of parent clauses of <c>
+           was missing in <ClauseVector>.
+***************************************************************/
+{
+  int     Position;
+  LIST    NewParents, NewPLits, Parents, PLits, Missing;
+  int     ParentNum, PLitNum;
+  CLAUSE  *Parent, Clause;
+
+  Missing = list_Nil();
+
+  for (Position = 0; Position < Size; Position++) {
+    clause_RemoveFlag(ClauseVector[Position], MARKED); 
+    clause_RemoveFlag(ClauseVector[Position], HIDDEN);
+  }
+
+  for (Position = 0; Position < Size; Position++)  {
+    Clause = ClauseVector[Position];
+    if (!clause_GetFlag(Clause, MARKED)) { 
+      clause_SetFlag(Clause, MARKED);
+      Parents    = clause_ParentClauses(Clause);
+      PLits      = clause_ParentLiterals(Clause);
+      NewParents = list_Nil();
+      NewPLits   = list_Nil();
+
+      while (!list_Empty(Parents)) {
+	ParentNum = (int)list_Car(Parents);
+	PLitNum   = (int)list_Car(PLits);
+	/* Binary search for parent clause with number <ParentNum>. */
+	Parent = bsearch((const void*)ParentNum, ClauseVector, Size,
+			 sizeof(CLAUSE), pcheck_CompareNumberAndClause);
+	if (Parent == NULL) {
+	  Missing = list_Cons((POINTER)ParentNum, Missing); 
+	  clause_SetFlag(Clause, HIDDEN);
+	} else {
+	  if (clause_GetFlag(*Parent, HIDDEN))
+	    clause_SetFlag(Clause, HIDDEN);
+	  NewParents  = list_Cons((POINTER)*Parent, NewParents);
+	  NewPLits    = list_Cons((POINTER)PLitNum, NewPLits);
+	}
+	Parents = list_Cdr(Parents); 
+	PLits   = list_Cdr(PLits);
+      }
+      list_Delete(clause_ParentClauses(Clause));
+      list_Delete(clause_ParentLiterals(Clause));
+      NewParents = list_NReverse(NewParents);
+      NewPLits   = list_NReverse(NewPLits);
+      clause_SetParentClauses(Clause, NewParents);
+      clause_SetParentLiterals(Clause, NewPLits);
+    } /* if clause is not marked */
+  } /* for all clauses */
+ 
+  return Missing;
+}
+
+
+static int pcheck_CompareClauseNumber(const void* C1, const void* C2)
+/**************************************************************
+  INPUT  : Two pointers to CLAUSEs.
+  RETURNS: 1) a negative number if the number of C1 is < number of C2.
+           2) 0 if C1 and C2 have the same clause number
+              (that means a possible bug in SPASS)
+           3) a positive number if number of C1 > number of C2
+  EFFECT:  This function is used as parameter to the qsort function.
+************************************************************/
+{
+  return clause_Number(*(const CLAUSE*)C1) - clause_Number(*(const CLAUSE*)C2);
+}
+
+
+static LIST pcheck_ConvertParentsInList(LIST List)
+/**************************************************************
+  INPUT:   A list of clauses.
+  RETURNS: The list of missing parent clause numbers from the list 
+  EFFECTS: Parent numbers are converted to pointers
+***************************************************************/
+{
+  int     Size, Index;
+  CLAUSE* ClauseVector;
+  LIST    Missing;
+
+  Size = list_Length(List);
+  if (Size == 0)
+    return list_Nil();
+
+  /* convert list into vector for binary search */
+  ClauseVector = (CLAUSE*)memory_Malloc(sizeof(CLAUSE) * Size);
+  for (Index = 0; !list_Empty(List); List = list_Cdr(List), Index++)
+    ClauseVector[Index] = list_Car(List);
+
+  /* sort the clauses in vector by increasing clause number */
+  qsort(ClauseVector, Size, sizeof(CLAUSE), pcheck_CompareClauseNumber);
+
+  /* convert parent lists */
+  Missing = pcheck_ForceParentNumbersToPointersInVector(ClauseVector, Size);
+  
+  memory_Free(ClauseVector, sizeof(CLAUSE) * Size);
+  return Missing;
+}
+
+
+LIST pcheck_ConvertParentsInSPASSProof(PROOFSEARCH Search, LIST EmptyClauses) 
+/**************************************************************
+  INPUT  : A proofsearch object with clauses sorted by weight
+           and an unsorted list <EmptyClauses>
+  RETURNS: The lists, where the clauses in <EmptyClauses> are
+           now sorted by weight, and parent numbers
+           in the clauses are replaced by parent pointers
+***************************************************************/
+{
+  LIST    AllLists; 
+  LIST    Missing;
+
+  AllLists = list_Nconc(list_Copy(prfs_DocProofClauses(Search)),
+			list_Copy(EmptyClauses));
+  AllLists = list_Nconc(list_Copy(prfs_UsableClauses(Search)), AllLists);
+  AllLists = list_Nconc(list_Copy(prfs_WorkedOffClauses(Search)), AllLists);
+  
+  AllLists = pcheck_ClauseNumberMergeSort(AllLists);
+  Missing  = pcheck_ConvertParentsInList(AllLists);
+  list_Delete(AllLists);
+
+  return Missing;
+}
+
+
+static LIST pcheck_ParentNumbersToParents(LIST Proof)
+/**************************************************************
+  INPUT:   A list of clauses, representing a proof.
+  RETURNS: The list, where parent numbers in the
+           parent list of clauses are replaced
+           by the parents (pointers).
+  CAUTION: For finding the clause corresponding to a
+           a clause number, the <Proof> list is searched
+	   with binary search. This is correct only if
+	   the clause numbers in <Proof> are increasing.
+************************************************************/
+{
+  LIST    ScanClauses;
+  int     ProofLength, Position;
+  CLAUSE* ClauseVector;
+
+  if (list_Empty(Proof))
+    return list_Nil();
+
+  /* convert list into vector for binary search */
+  ProofLength  = list_Length(Proof);
+  ClauseVector = (CLAUSE*) memory_Malloc(ProofLength * sizeof(CLAUSE));
+
+  for (ScanClauses = Proof, Position = 0; !list_Empty(ScanClauses);
+       ScanClauses = list_Cdr(ScanClauses), Position++) {
+    ClauseVector[Position] = list_Car(ScanClauses);
+  }
+
+  /* sort the clauses in vector by increasing clause number */
+  qsort(ClauseVector, ProofLength, sizeof(CLAUSE), pcheck_CompareClauseNumber);
+ 
+  /* convert parent lists */
+  pcheck_ParentNumbersToPointersInVector(ClauseVector, ProofLength);
+ 
+  memory_Free(ClauseVector, ProofLength * sizeof(CLAUSE));
+
+  return Proof;
+}
+
+
+LIST pcheck_ParentPointersToParentNumbers(LIST Clauses)
+/**************************************************************
+ INPUT  : A list of clauses                                                      
+ RETURNS: The list with parent pointers replaced by
+          parent numbers
+ EFFECTS: Sets marks on all clauses.                            
+***************************************************************/
+{
+  LIST ScanClauses;
+  LIST ScanParents;
+
+  pcheck_ClauseListRemoveFlag(Clauses, MARKED);
+
+  for (ScanClauses = Clauses; !list_Empty(ScanClauses); ScanClauses = list_Cdr(ScanClauses)) {
+    if (!clause_GetFlag(list_Car(ScanClauses), MARKED)) {
+      for (ScanParents = clause_ParentClauses(list_Car(ScanClauses)); !list_Empty(ScanParents);
+	   ScanParents = list_Cdr(ScanParents))
+	list_Rplaca(ScanParents, (POINTER)clause_Number(list_Car(ScanParents))); 
+      clause_SetFlag(list_Car(ScanClauses), MARKED);
+    }
+  }
+  return Clauses;
+}
+
+
+LIST pcheck_ConvertTermListToClauseList(LIST ProofRest, FLAGSTORE Flags,
+					PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A list of quintupels (lists) representing a proof,
+           a flag store, and a precedence.
+  RETURNS: The conversion of this list into the internal clause
+           structure. For each clause, the numbers of parent
+	   clauses are replaced by pointers to the parents.
+***************************************************************/
+{
+  LIST    Clauses;
+  LIST    ProofLine;
+  TERM    ClauseTerm;
+  CLAUSE  Clause;
+  int     Level;
+  int     ClauseNumber;
+  LIST    ParentLabels;
+  LIST    ParentIds;     
+  LIST    ParentLits;    /* this is a dummy list; parent lits are not yet specified in a SPASS proof */
+  RULE    Origin;
+  char*   ClauseLabel;
+
+  Clauses = list_Nil();  /* result */
+
+  while (!list_Empty(ProofRest)) {    
+    /* break proof line into components */
+    ProofLine     = list_Car(ProofRest);
+    
+    ClauseLabel   = list_First(ProofLine);
+    ClauseTerm    = list_Second(ProofLine);    
+    /* replace by NULL clause, since dfg_CreateClauseFromTerm deletes clause ! */
+    list_Rplaca(list_Cdr(ProofLine), clause_Null()); 
+    ParentLabels  = (LIST)list_Third(ProofLine);
+    Level         = (int)list_Fourth(ProofLine);
+    Origin        = (RULE)list_Fifth(ProofLine);
+
+    /* Conversion */
+    Clause       = dfg_CreateClauseFromTerm(ClauseTerm, TRUE, Flags,Precedence);
+    /* It's necessary to update the weight since dfg_CreateClauseFromTerm */
+    /* doesn't set it. */
+    clause_UpdateWeight(Clause, Flags);
+    ClauseNumber = pcheck_LabelToNumber(ClauseLabel);
+    ParentIds    = list_Nil();
+    ParentLits   = list_Nil();
+
+    while (!list_Empty(ParentLabels)) {
+      ParentIds  = list_Cons((POINTER)pcheck_LabelToNumber(list_Car(ParentLabels)), ParentIds); 
+      ParentLits = list_Cons(0, ParentLits);
+      ParentLabels   = list_Cdr(ParentLabels);
+    }
+    
+    /* set all data */
+    clause_SetNumber(Clause, ClauseNumber);
+    ParentIds = list_NReverse(ParentIds);
+    clause_SetParentClauses(Clause, ParentIds);
+    clause_SetParentLiterals(Clause, ParentLits);
+    Clause->origin = Origin;
+
+    clause_SetSplitLevel(Clause, Level); 
+    if (Level > 0) {
+      clause_ClearSplitField(Clause);
+      clause_SetSplitFieldBit(Clause, Level);
+    } else 
+      clause_SetSplitField(Clause, (SPLITFIELD)NULL,0);
+
+    clause_RemoveFlag(Clause, MARKED);
+    Clauses   = list_Cons(Clause, Clauses);
+    ProofRest = list_Cdr(ProofRest);  
+  }
+  Clauses = list_NReverse(Clauses);
+  
+  /* convert parent numbers to pointers */
+  Clauses = pcheck_ParentNumbersToParents(Clauses);
+  
+  return Clauses;
+}
+
+
+static BOOL pcheck_ClauseIsUnmarked(CLAUSE C)
+/**************************************************************
+  INPUT:   A clause
+  RETURNS: The value of the clauses MARKED flag
+***************************************************************/
+{
+  return !clause_GetFlag(C, MARKED);
+}
+
+
+static void pcheck_RemoveUnmarkedFromTableau(TABLEAU T)
+/**************************************************************
+  INPUT:   A tableau
+  RETURNS: Nothing.
+  EFFECTS: Delete all clauses that have the MARKED flag
+           set from tableau.
+***************************************************************/
+{
+  if (tab_IsEmpty(T))
+    return;
+  
+  tab_SetClauses(T, list_DeleteElementIf(tab_Clauses(T),
+					 (BOOL (*)(POINTER))pcheck_ClauseIsUnmarked));
+  
+  pcheck_RemoveUnmarkedFromTableau(tab_LeftBranch(T));
+  pcheck_RemoveUnmarkedFromTableau(tab_RightBranch(T));
+}
+
+
+static void pcheck_CollectUnmarkedSplits(TABLEAU T, LIST* Splits)
+/**************************************************************
+  INPUT:   A tableau, a list of clauses by reference
+  RETURNS: Nothing.
+  EFFECTS: Add all split clauses in the tableau that are not
+           marked to the <Splits> list.
+***************************************************************/
+{
+  LIST Scan;
+
+  if (tab_IsEmpty(T))
+    return;
+
+  for (Scan = tab_Clauses(T); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    if (!clause_GetFlag(list_Car(Scan), MARKED) && clause_IsFromSplitting(list_Car(Scan))) 
+      (*Splits) = list_Cons(list_Car(Scan), *Splits);
+  }
+  
+  pcheck_CollectUnmarkedSplits(tab_LeftBranch(T), Splits);
+  pcheck_CollectUnmarkedSplits(tab_RightBranch(T), Splits);
+}
+
+
+/* EK: unused, only recursive */
+static void pcheck_TableauSplitsComplete(TABLEAU T)
+/**************************************************************
+  INPUT  : A tableau
+  RETURNS: Checks that every split has exactly two or no
+           successors. This condition must be true after
+           tab_RemoveRedundantSplits has been called.
+***************************************************************/
+{
+  if (tab_IsEmpty(T))
+    return;
+  
+  if (tab_RightBranchIsEmpty(T) && !tab_LeftBranchIsEmpty(T)) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n Error: Split of clause %d has no right branch.\n", 
+			 clause_Number(tab_SplitClause(T)));
+    misc_FinishUserErrorReport();
+  }
+ 
+  if (!tab_RightBranchIsEmpty(T) && tab_LeftBranchIsEmpty(T)) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n Error: Split of clause %d has no left branch.\n", 
+			 clause_Number(tab_SplitClause(T)));
+    misc_FinishUserErrorReport();
+  }
+  
+  pcheck_TableauSplitsComplete(tab_LeftBranch(T));
+  pcheck_TableauSplitsComplete(tab_RightBranch(T));
+}
+
+
+static void pcheck_RightSplitParents(CLAUSE SplitClause, CLAUSE RightSplitClause,
+				     CLAUSE LeftSplitClause)
+/**************************************************************
+  INPUT:   A split clause, and its left and right successors
+  EFFECTS: Prints an error message if the split is not correctly
+           closed.
+***************************************************************/
+{
+  LIST Scan;
+  BOOL HasEmpty, ContainsSplitClause;
+
+  HasEmpty = ContainsSplitClause = FALSE;
+
+  for (Scan = clause_ParentClauses(RightSplitClause);
+       !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    if (clause_IsEmptyClause(list_Car(Scan)))
+      HasEmpty = TRUE;
+    if (clause_Number(list_Car(Scan)) == clause_Number(SplitClause)) 
+      ContainsSplitClause = TRUE; 
+  }
+  
+  if (!HasEmpty) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n Error: Right split clause %d has no empty clause as parent.\n", 
+			 clause_Number(SplitClause));
+    misc_FinishUserErrorReport();
+  }
+
+  if (!ContainsSplitClause) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n Error: Right split clause %d", clause_Number(SplitClause));
+    misc_UserErrorReport(" does not have its split parent as parent clause.\n");
+    misc_FinishUserErrorReport();
+  }
+}
+
+
+
+/* EK: unused, only recursive */
+static void pcheck_SplitFormats(TABLEAU T)
+/**************************************************************
+  INPUT  : A tableau
+  RETURNS: TRUE iff all splits:
+           - have generated negations of the left split clause
+ 	     if the left split clause is ground
+	   - the conditions for right split clauses are
+             as demanded in pcheck_RightSplitParents
+***************************************************************/
+{
+  LIST Scan;
+
+  if (tab_IsEmpty(T))
+    return;
+
+  /* for right splits, check that parents have an empty clause */
+  /* and the split clause as a parent */
+
+  for (Scan = tab_RightSplitClauses(T); !list_Empty(Scan);
+       Scan = list_Cdr(Scan)) {
+    pcheck_RightSplitParents(tab_SplitClause(T), list_Car(Scan),
+			     tab_LeftSplitClause(T));
+  }
+    
+  pcheck_SplitFormats(tab_RightBranch(T));
+  pcheck_SplitFormats(tab_LeftBranch(T));
+}
+
+
+static void pcheck_SplitLevels(TABLEAU T)
+/**************************************************************
+  INPUT  : A Tableau
+  RETURNS: TRUE iff all clauses in the tableau that
+           are not splitting clauses have the max split
+    	   level of their parents.
+  CAUTION: We assume that <T> has correct and complete split
+           entries. See pcheck_SplitToProblems.
+***************************************************************/
+{
+  LIST   Scan;
+  CLAUSE Clause;
+  int    CorrectLevel;
+
+  if (tab_IsEmpty(T))
+    return;
+
+  /* check split levels */
+  for (Scan = tab_Clauses(T); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    Clause = list_Car(Scan);
+    if (!list_Empty(clause_ParentClauses(Clause))
+	&& !clause_IsFromSplitting(Clause)) {
+ 
+     CorrectLevel = pcheck_MaxParentSplitLevel(Clause);
+     if (clause_SplitLevel(Clause) != CorrectLevel) {
+       misc_StartUserErrorReport();
+       misc_UserErrorReport("\n Error: Split level of clause %d should be %d.\n",
+			    clause_Number(Clause), CorrectLevel);
+       misc_FinishUserErrorReport();
+     }
+    }
+  }
+
+  pcheck_SplitLevels(tab_RightBranch(T));
+  pcheck_SplitLevels(tab_LeftBranch(T));
+}
+
+
+/* EK: unused, only recursive */
+static void pcheck_SplitPrecheck(TABLEAU T)
+/**************************************************************
+  INPUT  : A tableau.
+  EFFECTS: Stops and prints an error message if a left half
+           of a split does not subsume its parents, or
+	   if negations have been generated for a non-ground
+	   left split clause.
+***************************************************************/
+{
+  if (tab_IsEmpty(T))
+    return;
+  
+  if (!subs_Subsumes(tab_LeftSplitClause(T), tab_SplitClause(T), -1, -1)) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n Error: Incorrect split of %d,", tab_SplitClause(T));
+    misc_UserErrorReport(" left half of split does not subsume splitted clause.\n");			 
+    misc_FinishUserErrorReport();
+  }
+
+  if (list_Length(tab_RightSplitClauses(T)) > 1 &&
+      !clause_IsGround(tab_LeftSplitClause(T))) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n Error: Incorrect split of %d,", tab_SplitClause(T));
+    misc_UserErrorReport(" non-ground split generated more than two clause.\n");
+    misc_FinishUserErrorReport();
+  }
+
+  pcheck_SplitPrecheck(tab_LeftBranch(T));
+  pcheck_SplitPrecheck(tab_RightBranch(T));
+}
+
+
+BOOL pcheck_BuildTableauFromProof(LIST Proof, TABLEAU* Tableau)
+/**************************************************************
+  INPUT  : A list of clauses representing a proof, and a pointer
+           to a tableau used as return value.
+  RETURNS: TRUE iff no errors occurred, FALSE otherwise.
+           If TRUE is returned <Tableau> is set to a tableau
+	   representing the proof.
+  EFFECTS: Errors are commented when they occur.
+***************************************************************/
+{
+  LIST     ProofRest;
+  TABLEAU  SplitPos;
+  TABPATH  Path;
+  CLAUSE   Clause;
+  int      ClauseLevel, SplitLevel;
+  int      ProofDepth;
+
+  if (list_Empty(Proof)) {
+    *Tableau = tab_EmptyTableau();
+    return TRUE;
+  }
+
+  ProofDepth = pcheck_MaxSplitLevel(Proof);
+  *Tableau   = tab_CreateNode();
+  Path       = tab_PathCreate(ProofDepth, *Tableau);
+
+  ProofRest = Proof;
+  while (!list_Empty(ProofRest)) {
+
+    SplitLevel  = tab_PathLength(Path);
+    Clause      = list_Car(ProofRest);
+    ClauseLevel = clause_SplitLevel(Clause); 
+
+    /* Special treatment for clauses that result from a splitting step */
+    if (pcheck_ClauseIsFromSplit(Clause)) {
+
+      if (ClauseLevel == 0) {
+	misc_StartUserErrorReport();
+	misc_UserErrorReport("\n Error: Split level of split clause %d is 0.\n", clause_Number(Clause));
+	misc_FinishUserErrorReport();
+      }
+
+      if (ClauseLevel > SplitLevel+1) {
+	misc_StartUserErrorReport();
+	misc_UserErrorReport("\n Error: Split level of split clause %d", clause_Number(Clause));
+	misc_UserErrorReport(" is not increment of current split level.\n");
+	misc_FinishUserErrorReport();
+      }
+
+      SplitPos = tab_PathNthNode(Path, ClauseLevel-1);
+
+      if (pcheck_ClauseIsFromLeftSplit(Clause)) {
+	/* Left branch of a splitting step */
+	if (!tab_LeftBranchIsEmpty(SplitPos)) {
+	  misc_StartUserErrorReport();
+	  misc_UserErrorReport("\n Error: Multiple left splits for clause %d.\n", 
+			       clause_Number(tab_SplitClause(SplitPos)));
+	  misc_FinishUserErrorReport();
+	}
+
+	Path = tab_PathPrefix(ClauseLevel-1, Path);
+	tab_SetSplitClause(SplitPos, list_Car(clause_ParentClauses(Clause)));
+	tab_SetLeftSplitClause(SplitPos, Clause);
+	tab_AddSplitAtCursor(Path, TRUE);
+      } else {
+	/* Right branch of a splitting step */
+	if (tab_RightBranchIsEmpty(SplitPos)) {
+	  
+	  if (tab_LeftBranchIsEmpty(SplitPos)) {
+	    misc_StartUserErrorReport();
+	    misc_UserErrorReport("\n Error: Right split with incorrect split level, clause %d.\n", 
+				 clause_Number(Clause));
+	    misc_FinishUserErrorReport();
+	  }
+
+	  Path = tab_PathPrefix(ClauseLevel-1, Path);
+	  tab_AddSplitAtCursor(Path, FALSE);
+	}
+	tab_AddRightSplitClause(SplitPos, Clause); 
+      } /* clause from right split */
+    } /* clause from split */
+      
+    if (ClauseLevel > tab_PathLength(Path)) {
+      misc_StartUserErrorReport();
+      misc_UserErrorReport("\n Error: Split level of clause %d greater than current level.\n", 
+			   clause_Number(Clause));
+      misc_FinishUserErrorReport();
+    }
+    tab_AddClauseOnItsLevel(Clause, Path); 
+    
+    ProofRest = list_Cdr(ProofRest);   
+  } /* while proof is not empty */
+
+
+  tab_PathDelete(Path);
+
+  return TRUE;
+}
+
+
+static BOOL pcheck_TableauJustificationsRec(TABLEAU T, TABPATH Path)
+/**************************************************************
+  INPUT  : A Tableau <T>, a <Path> in the tableau
+  RETURNS: TRUE iff all clauses in the last node of the
+           path are correctly justified.
+***************************************************************/
+{
+  CLAUSE  Clause;
+  LIST    ScanClauses;
+  LIST    ScanParents;
+  LIST    Parents;
+  CLAUSE  Parent;
+  BOOL    Ok, RightSplit;
+
+  if (tab_IsEmpty(T))
+    return TRUE;
+
+  Ok = TRUE; 
+
+  /* for each clause, check that its parents have been justified */
+
+  for (ScanClauses = tab_Clauses(tab_PathTop(Path));
+       !list_Empty(ScanClauses); ScanClauses = list_Cdr(ScanClauses)) {
+
+    Clause  = list_Car(ScanClauses);
+    Parents = clause_ParentClauses(Clause);
+    
+    RightSplit = pcheck_ClauseIsFromRightSplit(Clause); 
+    
+    /* check all parents */
+    
+    for (ScanParents = Parents; !list_Empty(ScanParents); 
+	 ScanParents = list_Cdr(ScanParents)) {
+      
+      Parent = list_Car(ScanParents);
+      
+      if ((!(RightSplit && clause_IsEmptyClause(Parent)) &&
+	  !(RightSplit && pcheck_ClauseIsFromLeftSplit(Parent))) ||
+	  (clause_Number(Parent) > clause_Number(Clause)) ) {
+	if (!tab_PathContainsClause(Path, Parent)) {
+	  misc_StartUserErrorReport();
+	  misc_UserErrorReport("\n Error: Parent clause with number %d is not yet justified.\n", 
+			       clause_Number(Parent));
+	  misc_FinishUserErrorReport();
+	}
+      }
+    }
+  }  /* for all clauses in current node */
+  
+  
+  /* Recursion */
+  
+  if (!tab_LeftBranchIsEmpty(T)) {
+    Path = tab_PathPush(tab_LeftBranch(T), Path);
+    Ok   = Ok && pcheck_TableauJustificationsRec(tab_LeftBranch(T), Path);
+    Path = tab_PathPop(Path);
+  }
+  
+  if (!tab_RightBranchIsEmpty(T)) {
+    Path = tab_PathPush(tab_RightBranch(T), Path);
+    Ok   = Ok && pcheck_TableauJustificationsRec(tab_RightBranch(T), Path);
+    Path = tab_PathPop(Path);
+  }
+
+  return Ok;
+}
+
+static BOOL pcheck_TableauJustifications(TABLEAU T)
+/**************************************************************
+  INPUT  : A Tableau
+  RETURNS: TRUE iff for each clause in tableau, all its parent
+           clauses have been derived in a split on the same level
+	   or below.
+***************************************************************/
+{
+  TABPATH Path;
+  BOOL    Ok;
+
+  Path = tab_PathCreate(tab_Depth(T),T);
+  Ok   = pcheck_TableauJustificationsRec(T,Path); 
+  tab_PathDelete(Path);
+  
+  return Ok;
+}
+
+BOOL pcheck_TableauProof(TABLEAU* Tableau, LIST Proof)
+/**************************************************************
+  INPUT: 
+  RETURNS:                                                      
+***************************************************************/
+{
+  LIST RedundantClauses;
+  LIST EmptyClauses;
+  LIST UnmarkedSplits;
+
+  tab_LabelNodes(*Tableau);
+  /* print out current tableau */
+  if (pcheck_GenNamedCg) 
+    tab_WriteTableau(*Tableau, pcheck_CgName, pcheck_GraphFormat);
+  
+  RedundantClauses = list_Nil();
+  if (!pcheck_Quiet) {
+    fputs("pruning closed branches...", stdout);
+    fflush(stdout);
+  }
+  (*Tableau) = tab_PruneClosedBranches(*Tableau, &RedundantClauses);   /* delete descendants of already closed branches */
+  if (!pcheck_Quiet)
+    puts("finished.");
+
+  if (!pcheck_Quiet) {
+    fputs("removing incomplete splits...", stdout);
+    fflush(stdout);
+  }
+  (*Tableau) = tab_RemoveIncompleteSplits(*Tableau, &RedundantClauses);  /* reduce open node redundancies */
+  if (!pcheck_Quiet)
+    puts("finished.");
+  
+  list_Delete(RedundantClauses);
+
+  /* remove all clauses that are not needed for the empty clauses */
+  /* of the proof or for the tableau structure (splits) */
+
+  EmptyClauses = list_Nil();
+  tab_GetEarliestEmptyClauses(*Tableau, &EmptyClauses);
+  pcheck_ClauseListRemoveFlag(Proof, MARKED);
+  pcheck_MarkRecursive(EmptyClauses);
+  UnmarkedSplits = list_Nil();
+  pcheck_CollectUnmarkedSplits(*Tableau, &UnmarkedSplits);
+  pcheck_MarkRecursive(UnmarkedSplits);
+  pcheck_RemoveUnmarkedFromTableau(*Tableau); 
+  list_Delete(UnmarkedSplits);
+  list_Delete(EmptyClauses);
+
+  /* print reduced graph */
+  if (pcheck_GenRedCg) 
+    tab_WriteTableau(*Tableau, pcheck_RedCgName, pcheck_GraphFormat);
+
+  tab_SetSplitLevels(*Tableau);
+  pcheck_SplitLevels(*Tableau);
+  tab_CheckEmpties(*Tableau);
+
+ if (!tab_IsClosed(*Tableau)) {
+    puts("\nerror: tableau is not closed.");  
+    return FALSE;
+ }
+
+  /* check justifications */
+  if (!pcheck_Quiet) {
+    fputs("checking justifications...", stdout);
+    fflush(stdout);
+  }
+  if (!pcheck_TableauJustifications(*Tableau))
+    return FALSE;
+  if (!pcheck_Quiet)
+    puts("finished.");
+ 
+  return TRUE;
+}
+
+
+void pcheck_MarkRecursive(LIST Clauses)
+/**************************************************************
+  INPUT:   A list of clauses 
+  RETURNS: Nothing.                                                      
+  EFFECTS: Marks all <Clauses> and its ancestors with the
+           MARKED clause flag.
+***************************************************************/
+{
+  CLAUSE Clause;
+
+  for (; !list_Empty(Clauses); Clauses = list_Cdr(Clauses)) {
+    Clause = list_Car(Clauses);
+    if (!clause_GetFlag(Clause, MARKED)) {
+      pcheck_MarkRecursive(clause_ParentClauses(Clause)); 
+      clause_SetFlag(Clause, MARKED);
+    }
+  }
+}
+
+
+static LIST pcheck_CollectTermVariables(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: A list of terms. For each variable in <Term> the list
+           contains exactly one term representing the variable.
+  EFFECT:  Memory is allocated for the terms.
+***************************************************************/
+{
+  LIST Result, Scan;
+
+  Result = term_VariableSymbols(Term);
+  for (Scan = Result; !list_Empty(Scan); Scan = list_Cdr(Scan))
+    list_Rplaca(Scan, term_Create((SYMBOL)list_Car(Scan), list_Nil()));
+
+  return Result;
+}
+
+
+static BOOL pcheck_IsRightSplitHalf(CLAUSE C)
+/**************************************************************
+  INPUT  : A clause.
+  RETURNS: TRUE iff the following conditions are fulfilled:
+           - the first parent clause is an empty clause
+	   - the clause subsumes its second parent
+***************************************************************/
+{
+  LIST Parents;
+  BOOL Ok;
+
+  Parents = list_Copy(clause_ParentClauses(C));
+  Parents = list_PointerDeleteDuplicates(Parents);
+
+  Ok = FALSE;
+  if (list_Length(Parents) == 2 && clause_IsEmptyClause(list_First(Parents)))
+    Ok = subs_Subsumes(C, list_Second(Parents), -1, -1);
+
+  list_Delete(Parents);
+
+  return Ok;
+}
+
+
+static TERM pcheck_UnivClosure(TERM T)
+/**************************************************************
+  INPUT:   A term, representing a formula.
+  RETURNS: The universal closure of the term.
+  EFFECTS: <T> is part of the returned term!
+***************************************************************/
+{
+  LIST Vars;
+
+  Vars = pcheck_CollectTermVariables(T);
+  
+  if (list_Empty(Vars))
+    return T;
+  return fol_CreateQuantifier(fol_All(), Vars, list_List(T));
+}
+
+
+static TERM pcheck_ClauseToTerm(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A clause.
+  RETURNS: The clause represented as a TERM.
+***************************************************************/
+{
+  int  LitScan;
+  LIST Args;
+  TERM Lit;
+  TERM ClauseTerm;
+
+  Args = list_Nil();
+
+  for (LitScan = clause_FirstLitIndex(); LitScan <= clause_LastLitIndex(Clause);
+       LitScan++) {
+    Lit  = clause_LiteralSignedAtom(clause_GetLiteral(Clause, LitScan));
+    Args = list_Cons(term_Copy(Lit), Args);
+  }
+
+  if (list_Empty(Args))
+    Args = list_List(term_Create(fol_False(), list_Nil()));
+  
+  /* Build the disjunction of the literals */
+  if (list_Empty(list_Cdr(Args))) {   /* only one arg */
+    ClauseTerm = list_Car(Args);
+    list_Delete(Args);
+  } else
+    ClauseTerm = term_Create(fol_Or(), Args);
+  ClauseTerm = pcheck_UnivClosure(ClauseTerm);
+
+  return ClauseTerm;
+}
+
+
+static LIST pcheck_ClauseListToTermList(LIST Clauses)
+/**************************************************************
+  INPUT  : A list of clauses.
+  RETURNS: A new list containing the clauses represented as TERMs.
+***************************************************************/
+{
+  LIST Terms;
+
+  Terms = list_Nil();
+  for (; !list_Empty(Clauses); Clauses = list_Cdr(Clauses))
+    Terms = list_Cons(pcheck_ClauseToTerm(list_Car(Clauses)), Terms);
+  
+  return Terms;
+}
+
+
+static void pcheck_SaveNumberedDFGProblem(int Number, LIST Axioms,
+					  LIST Conjectures,
+					  const char* ProofFileName,
+					  const char* DestPrefix)
+/**************************************************************
+  INPUT  : A (clause) number, a list of axioms and conjectures,
+           and a filename (of the proof file of the currently
+	   checked proof)
+  RETURNS: Nothing.
+  EFFECTS: Saves a DFG file containing <Axioms> and <Conjectures>
+           under the name "<DestPrefix><Number>_<ProofFileName>"
+***************************************************************/
+{
+  char *Filename, *Tmp, *NumStr;
+  FILE *File;
+
+  NumStr   = string_IntToString(Number);
+  Tmp      = pcheck_GenericFilename(ProofFileName, NumStr);
+  Filename = string_Conc(DestPrefix, Tmp);
+    
+  File = misc_OpenFile(Filename, "w");
+  fol_FPrintDFGProblem(File, "{*Sub Proof*}", "{* Proof Checker *}",
+		       "unsatisfiable",
+		       "{* The problem is the correctness test for a single proof line *}",
+		       Axioms, Conjectures);
+  misc_CloseFile(File, Filename);
+
+  string_StringFree(NumStr);
+  string_StringFree(Tmp);
+  string_StringFree(Filename);
+}
+
+
+static void pcheck_SplitToProblems(TABLEAU T, const char* ProofFileName,
+				   const char* DestPrefix)
+/**************************************************************
+  INPUT:   A tableau, which isn't a leaf of the tableau tree,
+           the name of a proof file and a file name prefix used for
+	   generating files.
+  RETURNS: Nothing.
+  EFFECT:  This function generates proof check tasks for clauses
+           resulting from splitting steps and writes them to
+	   output files.
+  CAUTION: We assume that we get non-null clauses when calling
+           tab_SplitClause and tab_LeftSplitClause.
+***************************************************************/
+{
+  TERM SplitClauseTerm, LeftClauseTerm, RightClauseTerm;
+  TERM Equiv, Disj, Tmp;
+  LIST Conj, Args, Negations;
+
+#ifdef CHECK
+  if (tab_IsLeaf(T)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In pcheck_SplitToProblems: Tableau is a leaf of the ");
+    misc_ErrorReport("tableau tree.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  SplitClauseTerm = pcheck_ClauseToTerm(tab_SplitClause(T));
+  LeftClauseTerm  = pcheck_ClauseToTerm(tab_LeftSplitClause(T));
+  
+  /* by default, take all right split clauses as negations       */
+  /* if the first clause is the second half of a split clause,   */
+  /* take only the rest of the right split clauses as negations. */
+
+  Negations = tab_RightSplitClauses(T);
+  if (!list_Empty(Negations) && pcheck_IsRightSplitHalf(list_Car(Negations))) {
+    /* EK: Meiner Meinung nach ist es eine Invariante, daß die erste */
+    /* Elternklausel die rechte Hälfte eines Splittings ist???  */
+    Negations = list_Cdr(Negations);
+    /* build C <=> C' v C''  */
+    RightClauseTerm = pcheck_ClauseToTerm(list_Car(tab_RightSplitClauses(T)));
+    Disj  = term_Create(fol_Or(), list_Cons(LeftClauseTerm, list_List(RightClauseTerm)));
+    Equiv = term_Create(fol_Equiv(), list_Cons(SplitClauseTerm, list_List(Disj)));
+    Conj  = list_List(Equiv);
+    
+    pcheck_SaveNumberedDFGProblem(clause_Number(tab_LeftSplitClause(T)),
+				  list_Nil(), Conj, ProofFileName, DestPrefix);
+    term_DeleteTermList(Conj);
+  }
+  
+  Args = list_Nil();
+
+  /* build conjunction of negations, if there are any. */
+  if (!list_Empty(Negations)) {
+    LeftClauseTerm = pcheck_ClauseToTerm(tab_LeftSplitClause(T));
+    Args  = pcheck_ClauseListToTermList(Negations);
+    /* Build the conjunction */
+    if (list_Empty(list_Cdr(Args))) {  /* only one arg */
+      Tmp = list_Car(Args);
+      list_Delete(Args);
+    } else
+      Tmp = term_Create(fol_And(), Args);
+    Tmp   = term_Create(fol_Not(), list_List(Tmp));
+    Equiv = term_Create(fol_Implies(),list_Cons(Tmp,list_List(LeftClauseTerm)));
+    Conj  = list_List(Equiv);
+    
+    /* problem id is number of right part of split clause, if it exists,
+       number of first negation otherwise */
+    pcheck_SaveNumberedDFGProblem(clause_Number(list_Car(tab_RightSplitClauses(T))), 
+				  list_Nil(), Conj, ProofFileName, DestPrefix);
+    term_DeleteTermList(Conj);
+  }
+}
+
+
+void pcheck_TableauToProofTask(TABLEAU T, const char* ProofFileName,
+			       const char* DestPrefix)
+/**************************************************************
+  INPUT:   A Tableau, two strings for filename generation.
+  RETURNS: Nothing.
+  EFFECTS: Generates DFG problem files for each clause in the tableau.
+           The problem asserts that the clause follows from
+	   its parents. For splits, see pcheck_SplitToProblems
+***************************************************************/
+{
+  LIST   Scan;
+  LIST   Axioms, Conj, Help;
+  CLAUSE Clause;
+
+  if (tab_IsEmpty(T))
+    return;
+
+  /* treat the splitting clauses at inner nodes of the tableau tree */
+  if (!tab_IsLeaf(T))
+    pcheck_SplitToProblems(T, ProofFileName, DestPrefix);
+ 
+  /* treat derived clauses that don't result from splitting */
+  for (Scan = tab_Clauses(T); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    Clause = list_Car(Scan);
+    if (!clause_IsFromSplitting(Clause) &&
+	!list_Empty(clause_ParentClauses(Clause))) {
+      Axioms = list_Copy(clause_ParentClauses(Clause));
+      Axioms = list_PointerDeleteDuplicates(Axioms);
+      Help   = Axioms;
+      Axioms = pcheck_ClauseListToTermList(Axioms);
+      list_Delete(Help);
+      Conj   = list_List(pcheck_ClauseToTerm(Clause));
+      pcheck_SaveNumberedDFGProblem(clause_Number(Clause), Axioms, Conj,
+				    ProofFileName, DestPrefix);
+      term_DeleteTermList(Axioms);
+      term_DeleteTermList(Conj);
+    }
+  }
+  
+  /* recursion */
+  pcheck_TableauToProofTask(tab_RightBranch(T), ProofFileName, DestPrefix);
+  pcheck_TableauToProofTask(tab_LeftBranch(T), ProofFileName, DestPrefix);
+}
+
+
+int pcheck_SeqProofDepth(LIST Proof)
+/**************************************************************
+  INPUT  : A sequential proof (list of clauses)
+  RETURNS: The maximum clause depth in the proof
+***************************************************************/ 
+{
+  int Max;
+
+  Max = 0;
+  for ( ; !list_Empty(Proof); Proof = list_Cdr(Proof)) 
+    if (clause_Depth(list_Car(Proof)) > Max)
+      Max = clause_Depth(list_Car(Proof));
+  
+  return Max;
+}
+
+
+LIST pcheck_ReduceSPASSProof(LIST Proof)
+/**************************************************************
+  INPUT:   A list of clauses representing a SPASS proof.
+           Parents are pointers.
+  RETURNS: A list of clauses were incomplete splits
+           and closed branches with descendants have been
+	   removed.
+***************************************************************/  
+{
+  LIST    EmptyClauses, RedundantClauses;
+  LIST    ReducedProof;
+  TABLEAU Tableau;
+  LIST    UnmarkedSplits;
+
+  if (!pcheck_BuildTableauFromProof(Proof, &Tableau)) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n Error: Proof could not be translated into a closed tableau.\n");
+    misc_FinishUserErrorReport();
+  }
+
+  RedundantClauses = list_Nil();
+  Tableau = tab_PruneClosedBranches(Tableau, &RedundantClauses);
+  Tableau = tab_RemoveIncompleteSplits(Tableau, &RedundantClauses);
+  list_Delete(RedundantClauses);
+  
+  tab_SetSplitLevels(Tableau);
+  
+  /* 
+   *  get minimal proof: First find earliest derived empty clauses,
+   *  then recursively mark ancestors of these clauses. Put
+   *  only marked clauses in <ReducedProof>.
+   */
+
+  EmptyClauses = list_Nil();
+  tab_GetEarliestEmptyClauses(Tableau, &EmptyClauses);
+  pcheck_ClauseListRemoveFlag(Proof, MARKED);
+  pcheck_MarkRecursive(EmptyClauses);
+  UnmarkedSplits = list_Nil();
+  pcheck_CollectUnmarkedSplits(Tableau, &UnmarkedSplits);
+  pcheck_MarkRecursive(UnmarkedSplits);
+  pcheck_RemoveUnmarkedFromTableau(Tableau); 
+  list_Delete(UnmarkedSplits);
+
+  ReducedProof = list_Nil(); 
+  tab_ToClauseList(Tableau, &ReducedProof);
+  ReducedProof = pcheck_ClauseNumberMergeSort(ReducedProof);
+
+  tab_Delete(Tableau);
+  list_Delete(EmptyClauses); 
+
+  return ReducedProof;
+}
+
+
+void pcheck_DeleteProof(LIST Proof)
+/**************************************************************
+  INPUT:   A Proof
+  RETURNS: Nothing.
+  EFFECTS: Frees memory associated with proof
+**************************************************************/
+{
+  LIST Line, Scan2, Scan1;
+  
+  Scan1 = Proof;
+  while (!list_Empty(Scan1)) {
+    Line = list_Car(Scan1);
+    
+    string_StringFree(list_Car(Line));
+    if (list_Second(Line) != clause_Null())                /* clause */
+      term_Delete(list_Second(Line));
+
+    /* delete labels in justification list and list itself */
+
+    for (Scan2 = list_Third(Line); !list_Empty(Scan2); Scan2 = list_Cdr(Scan2)) 
+      string_StringFree(list_Car(Scan2));
+    list_Delete(list_Third(Line));     
+
+    /* now contents of line are deleted. Delete line. */
+    list_Delete(Line);     
+    Scan1 = list_Cdr(Scan1);
+  }
+  list_Delete(Proof);
+}
+
+
+char* pcheck_GenericFilename(const char* Filename, const char* Id)
+/**************************************************************
+  INPUT:   Two strings.
+  RETURNS: A string with Suffix as new extension to Filename
+           (Filename = name.ext -> name_<Id>.prf)
+  EFFECTS: Memory is allocated for the returned string.
+**************************************************************/
+{	
+  char *Help1, *Help2;
+  int  i;
+
+  Help1 = string_Conc("_", Id); 
+  Help2 = string_Conc(Help1, pcheck_ProofFileSuffix); 
+  string_StringFree(Help1);
+  
+  /* remove filename extension */
+  for (i = 0; Filename[i] != '.' && i < strlen(Filename); i++)
+    /* empty */;
+  Help1 = string_Prefix(Filename, i);
+
+  return string_Nconc(Help1, Help2);  /* Help1 and Help2 are freed, too */
+}
+
+
+void pcheck_ClauseListRemoveFlag(LIST Clauses, CLAUSE_FLAGS Flag)
+/**************************************************************
+  INPUT:   A list of clauses and a clause flag
+  RETURNS: Nothing.
+  EFFECTS: Removes the <Flag> in all clauses in the list
+**************************************************************/
+{
+  for (; !list_Empty(Clauses); Clauses = list_Cdr(Clauses)) 
+    clause_RemoveFlag(list_Car(Clauses), Flag);
+}
+
+
+LIST pcheck_ClauseNumberMergeSort(LIST L)
+/**************************************************************
+  INPUT:   A list of clauses  
+  RETURNS: The sorted list: clause_Number(L[i]) < clause_Number(L[i+1])
+  EFFECTS: Destructive
+***************************************************************/
+{
+  return clause_NumberSort(L);
+}
diff --git a/test/spass/proofcheck.h b/test/spass/proofcheck.h
new file mode 100644
index 0000000000000000000000000000000000000000..4f697468dc7c1d08897c5eeb7273855ca42811af
--- /dev/null
+++ b/test/spass/proofcheck.h
@@ -0,0 +1,82 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *             PROOF CHECKING                             * */
+/* *                                                        * */
+/* *  Copyright (C) 1998, 1999, 2000, 2001                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+
+/* $RCSfile$ */
+
+#ifndef _PROOFCHECK_H_
+#define _PROOFCHECK_H_
+
+#include "options.h"
+
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#include "list.h"
+#include "vector.h"
+
+#include "misc.h"
+#include "dfg.h"
+#include "foldfg.h"
+#include "flags.h"
+#include "clause.h"
+#include "tableau.h"
+#include "search.h"
+#include "dfg.h"
+
+
+LIST  pcheck_ReduceSPASSProof(LIST);
+char* pcheck_GenericFilename(const char*, const char*);
+int   pcheck_SeqProofDepth(LIST);
+void  pcheck_DeleteProof(LIST);
+BOOL  pcheck_BuildTableauFromProof(LIST, TABLEAU*);
+LIST  pcheck_ConvertTermListToClauseList(LIST, FLAGSTORE, PRECEDENCE);
+void  pcheck_TableauToProofTask(TABLEAU, const char*, const char*);
+BOOL  pcheck_TableauProof(TABLEAU*, LIST);
+LIST  pcheck_ParentPointersToParentNumbers(LIST);
+LIST  pcheck_ConvertParentsInSPASSProof(PROOFSEARCH, LIST);
+void  pcheck_MarkRecursive(LIST); 
+LIST  pcheck_ClauseNumberMergeSort(LIST);
+void  pcheck_ClauseListRemoveFlag(LIST, CLAUSE_FLAGS);
+
+#endif
+
+
+
diff --git a/test/spass/ras.h b/test/spass/ras.h
new file mode 100644
index 0000000000000000000000000000000000000000..9e3f4232da1a1e78bf37a5ddd48f342deb30445f
--- /dev/null
+++ b/test/spass/ras.h
@@ -0,0 +1,298 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *             RANDOM ACCESS STACK                        * */
+/* *                                                        * */
+/* *  $Module:   RAS                                        * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1999, 2000, 2001 MPI fuer Informatik    * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                         * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+#ifndef _RAS_
+#define _RAS_
+
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "misc.h"
+#include "memory.h"
+
+
+/**************************************************************/
+/* Constants and types                                        */
+/**************************************************************/
+
+#define ras_alloc   -1  /* index of size of allocated space */
+#define ras_top     -2  /* index of next free element */
+#define ras_head     2  /* size of stack head for management purposes */
+#define ras_stdsize 16  /* standard stack size */
+
+
+typedef POINTER *RAS;
+
+/* A RAS (Random Access Stack) is a pointer to an array of elements */
+/* where the actual size of the stack and its current top pointer   */
+/* are stored one and two cells before the array pointer.           */
+
+
+/**************************************************************/
+/* Inline Functions                                           */
+/**************************************************************/
+
+static __inline__ RAS ras_CreateWithSize(int size)
+/****************************************************************
+  INPUT:   The maximal expected size of the stack to create.
+  RETURNS: A new empty stack.
+*****************************************************************/
+{
+  RAS result;
+
+#ifdef CHECK
+  if (size <= 0) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In ras_CreateWithSize: size not positive.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  result            = (RAS) memory_Malloc((size + ras_head) * sizeof(POINTER));
+  result            = result + ras_head;  /* leave space for head */
+  result[ras_alloc] = (POINTER) size;
+  result[ras_top]   = (POINTER) 0;
+  return result;
+}
+
+
+static __inline__ RAS ras_Create(void)
+{
+  return ras_CreateWithSize(ras_stdsize);
+}
+
+
+static __inline__ void ras_Free(RAS ras)
+{
+  if (ras != NULL) {
+    memory_Free (
+      ras - ras_head,
+      (ras_head + (int) ras[ras_alloc]) * sizeof(POINTER)
+    );
+  }
+}
+
+
+static __inline__ RAS ras_InitWithSize(RAS ras, int size)
+/****************************************************************
+  INPUT:   A random access stack the maximal expected size of the
+           stack to init.
+  RETURNS: The initialized and potentially new stack.
+  CAUTION: Because it potentially frees the old stack this
+           function must be called inside an assignment like:
+              stack = ras_InitWithSize(stack, ...)
+*****************************************************************/
+{
+
+#ifdef CHECK
+  if (size <= 0) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In ras_InitWithSize: size not positive.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (size > (int) ras[ras_alloc]) {
+    ras_Free(ras);
+    ras = ras_CreateWithSize(size);
+  }
+  else
+    ras[ras_top] = (POINTER) 0;
+  return ras;
+}
+
+
+static __inline__ RAS ras_Init(RAS ras)
+/****************************************************************
+  INPUT:   A random access stack.
+  RETURNS: The initialized and potentially new stack.
+  CAUTION: Because it potentially frees the old stack this
+           function must be called inside an assignment like:
+              stack = ras_InitWithSize(stack, ...)
+*****************************************************************/
+{
+  return ras_InitWithSize(ras, ras_stdsize);
+}
+
+
+static __inline__ int ras_Size(RAS ras)
+{
+  return (int) ras[ras_top];
+}
+
+
+static __inline__ RAS ras_FastPush(RAS ras, POINTER entry)
+/*********************************************************
+  INPUT:   A random access stack and an element to push.
+  RETURNS: The modified stack.
+  CAUTION: The function does not care about stack overflow!
+**********************************************************/    
+{
+  int top;
+
+#ifdef CHECK
+  if (ras_Size(ras) == (int) ras[ras_alloc]) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In ras_FastPush: stack overflow.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  top          = ras_Size(ras);
+  ras[top++]   = entry;
+  ras[ras_top] = (POINTER) top;
+  return ras;
+}
+
+
+static __inline__ RAS ras_Push(RAS ras, POINTER entry)
+/*********************************************************
+  INPUT:   A random access stack and an element to push.
+  RETURNS: The modified and potentially new stack.
+  SUMMARY: Before the push the stack is checked for overflow
+           and in case of overflow its size is doubled while
+           elements are copied to the (new) stack.
+  CAUTION: Must be called inside an assignment:
+              stack = ras_Push(stack, ...)
+**********************************************************/  
+{
+  RAS old;
+  int oldsize;
+  POINTER *oldscan, *scan;
+
+  /* if not enough space allocated, double it: */
+  if (ras_Size(ras) == (int) ras[ras_alloc]) {
+    old          = ras;
+    oldsize      = (int) old[ras_alloc];
+    ras          = ras_CreateWithSize(oldsize * 2);
+    ras[ras_top] = (POINTER) oldsize;
+
+    /* copy entries: */
+    for (oldscan = old + oldsize - 1,scan = ras + oldsize - 1; oldscan >= old;
+        oldscan--, scan--)
+      *scan = *oldscan;
+
+    ras_Free(old);
+  }
+
+  return ras_FastPush(ras, entry);
+}
+
+
+static __inline__ BOOL ras_LegalIndex(RAS ras, int index)
+{
+  return 0 <= index && index < ras_Size(ras);
+}
+
+
+static __inline__ POINTER ras_Get(RAS ras, int index)
+{
+#ifdef CHECK
+  if (!ras_LegalIndex(ras, index)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In ras_Get: illegal stack index.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  return ras[index];
+}
+
+
+static __inline__ RAS ras_Set(RAS ras, int index, POINTER entry)
+{
+#ifdef CHECK
+  if (!ras_LegalIndex(ras, index)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In ras_Set: illegal stack index.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  ras[index] = entry;
+  return ras;
+}
+
+
+static __inline__ BOOL ras_Empty(RAS ras)
+{
+  return ras_Size(ras) == 0;
+}
+
+
+static __inline__ POINTER ras_Pop(RAS ras)
+{
+  int top;
+
+#ifdef CHECK
+  if (ras_Empty(ras)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In ras_Pop: empty stack.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  top          = ras_Size(ras) - 1;
+  ras[ras_top] = (POINTER) top;
+  return ras[top];
+}
+
+
+static __inline__ POINTER ras_Top(RAS ras)
+{
+#ifdef CHECK
+  if (ras_Empty(ras)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In ras_Top: empty stack.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  return ras[ras_Size(ras) - 1];
+}
+
+
+#endif
+
diff --git a/test/spass/renaming.c b/test/spass/renaming.c
new file mode 100644
index 0000000000000000000000000000000000000000..55c89c5a7d7b47bf780efcd6eccc4abcff63f3d8
--- /dev/null
+++ b/test/spass/renaming.c
@@ -0,0 +1,1508 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                   RENAMING                             * */
+/* *                                                        * */
+/* *  $Module:   RENAMING                                   * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "renaming.h"
+
+static NAT ren_STAMPID;
+
+static BOOL ren_RootDistanceSmaller(RENAMING,RENAMING);
+static BOOL ren_AFactorOk(TERM,TERM);
+static BOOL ren_BFactorOk(TERM,TERM);
+static BOOL ren_AExtraFactorOk(TERM,TERM);
+static BOOL ren_BExtraFactorOk(TERM,TERM);
+static BOOL ren_AFactorBigger3(TERM,TERM);
+static BOOL ren_BFactorBigger3(TERM,TERM);
+static TERM ren_FormulaRename(TERM, LIST, PRECEDENCE, LIST*);
+static LIST ren_GetRenamings(TERM, TERM, int);
+static BOOL ren_HasBenefit(TERM, TERM, int);
+static int  ren_Polarity(TERM);
+static BOOL ren_PFactorOk(TERM);
+static BOOL ren_PExtraFactorOk(TERM);
+static BOOL ren_PFactorBigger3(TERM);
+static BOOL ren_NotPFactorOk(TERM);
+static BOOL ren_NotPExtraFactorOk(TERM);
+static BOOL ren_NotPFactorBigger3(TERM);
+static void ren_ResetTermStamp(TERM);
+
+void ren_Init(void)
+/**********************************************************
+  INPUT:   None.
+  RETURNS: void.
+  EFFECT:  Initializes the renaming module, in particular
+           the stamp id used in this module.
+***********************************************************/
+{
+  ren_STAMPID = term_GetStampID();
+}
+
+static BOOL ren_RootDistanceSmaller(RENAMING Ren1, RENAMING Ren2)
+{
+  return term_RootDistanceSmaller(ren_Hit(Ren1), ren_Hit(Ren2));
+}
+
+
+static void ren_ResetTermStamp(TERM Term)
+/**********************************************************
+  INPUT:   A term.
+  RETURNS: void.
+  EFFECT:  The Term stamp of term as well as the stamps of 
+           all its subterms (up to atom level) are reset.
+***********************************************************/
+{
+  SYMBOL Top;
+ 
+  term_ResetTermStamp(Term);
+  Top = term_TopSymbol(Term);
+
+  if (!symbol_IsPredicate(Top)) {
+    if (fol_IsQuantifier(Top))
+      ren_ResetTermStamp(term_SecondArgument(Term));
+    else {
+      LIST Scan;
+      for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+	ren_ResetTermStamp(list_Car(Scan)); 
+    }
+  }
+}
+
+static BOOL ren_HasNEquivFathers(TERM Term1, TERM Term2, NAT n)
+/**********************************************************
+  INPUT:   Two terms, where <Term2> is a proper subterm of <Term1>
+           and a number.
+  RETURNS: TRUE if <Term2> has a <n>-father that are equivalences
+           and  below <Term1>
+***********************************************************/
+{
+  Term2 = term_Superterm(Term2);
+
+  while (Term1 != Term2) {
+    if (symbol_Equal(term_TopSymbol(Term2),fol_Equiv())) {
+      n--;
+      if (n == 0)
+	return TRUE;
+    }
+    Term2 = term_Superterm(Term2);
+  }
+
+  return FALSE;
+}
+
+
+static BOOL ren_PExtraFactorOk(TERM Term)
+/**********************************************************
+  INPUT:   A term.
+  RETURNS: TRUE if transforming the term <Term> in positive polarity context
+           results in more than two clauses.
+***********************************************************/
+{ 
+  SYMBOL Top;
+  TERM   T1, T2;
+  BOOL   Ok;
+
+  /* if <Term> has the stamp, it will be renamed */
+  if (term_HasTermStamp(Term) || term_IsAtom(Term))
+    return FALSE;
+
+  Top = term_TopSymbol(Term);
+  
+  if (fol_IsQuantifier(Top))
+    return ren_PExtraFactorOk(term_SecondArgument(Term));
+
+  if (symbol_Equal(Top,fol_Not()))
+    return ren_NotPExtraFactorOk(term_FirstArgument(Term));
+
+  if (symbol_Equal(Top,fol_Equiv())) {
+    T1 = term_FirstArgument(Term);
+    T2 = term_SecondArgument(Term);
+    return (ren_PFactorOk(T1) || ren_NotPFactorOk(T2) ||
+	    ren_NotPFactorOk(T1) || ren_PFactorOk(T2));
+  }
+  if (symbol_Equal(Top,fol_And())) {
+    return (list_Length(term_ArgumentList(Term)) > 2 ||
+	    ren_PFactorOk(term_FirstArgument(Term)) ||
+	    ren_PFactorOk(term_SecondArgument(Term)));
+  }
+  if (symbol_Equal(Top,fol_Implies())) {
+    T1 = term_FirstArgument(Term);
+    T2 = term_SecondArgument(Term);
+    Ok = ren_PFactorOk(T2);
+    return ((ren_NotPFactorOk(T1) && (Ok || ren_NotPExtraFactorOk(T1))) ||
+	    (Ok && ren_PExtraFactorOk(T2)));
+  }
+
+  if (symbol_Equal(Top,fol_Or())) {
+    LIST Scan;
+    Ok = FALSE; /* is set to TRUE if a subterm with p factor >1 occurred */
+    for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+      if (ren_PFactorOk(list_Car(Scan))) {
+	if (Ok || ren_PExtraFactorOk(list_Car(Scan)))
+	  return TRUE;  /* if two subterms with p>1 or one subterm with p>2 */
+	Ok = TRUE;
+      }
+  }
+
+  return FALSE; /* <Term> is a trivial disjunction */
+}
+
+static BOOL ren_PFactorOk(TERM Term)
+/**********************************************************
+  INPUT:   A term.
+  RETURNS: TRUE if transforming the term <Term> in positive polarity context
+           results in more than one clause.
+***********************************************************/
+{ 
+  SYMBOL Top;
+
+  /* if <Term> has the stamp, it will be renamed */
+  if (term_HasTermStamp(Term) || term_IsAtom(Term))
+    return FALSE;
+
+  Top = term_TopSymbol(Term);
+  
+  if (symbol_Equal(Top,fol_Equiv()) || symbol_Equal(Top,fol_And()))
+    return TRUE;
+
+  if (symbol_Equal(Top,fol_Not()))
+    return ren_NotPFactorOk(term_FirstArgument(Term));
+
+  if (fol_IsQuantifier(Top))
+    return ren_PFactorOk(term_SecondArgument(Term));
+
+  if (symbol_Equal(Top,fol_Implies()))
+    return (ren_NotPFactorOk(term_FirstArgument(Term)) ||
+	    ren_PFactorOk(term_SecondArgument(Term)));
+
+  if (symbol_Equal(Top,fol_Or())) {
+    LIST Scan;
+    for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+      if (ren_PFactorOk(list_Car(Scan)))
+	return TRUE;
+  }
+
+  return FALSE; /* <Term> is a trivial disjunction */
+}
+
+
+static BOOL ren_NotPExtraFactorOk(TERM Term)
+/**********************************************************
+  INPUT:   A term.
+  RETURNS: TRUE if transforming the term <Term> in negative polarity context
+           results in more than two clauses.
+***********************************************************/
+{ 
+  SYMBOL Top;
+
+  /* if <Term> has the stamp, it will be renamed */
+  if (term_HasTermStamp(Term) || term_IsAtom(Term))
+    return FALSE;
+
+  Top = term_TopSymbol(Term);
+  
+  if (symbol_Equal(Top,fol_Not()))
+    return ren_PExtraFactorOk(term_FirstArgument(Term));
+
+  if (fol_IsQuantifier(Top))
+    return ren_NotPExtraFactorOk(term_SecondArgument(Term));
+
+  if (symbol_Equal(Top,fol_Equiv())) {
+    TERM T1, T2;
+    T1 = term_FirstArgument(Term);
+    T2 = term_SecondArgument(Term);
+    return (ren_PFactorOk(T1) || ren_PFactorOk(T2) ||
+	    ren_NotPFactorOk(T1) || ren_NotPFactorOk(T2));
+  }
+  if (symbol_Equal(Top,fol_Or())) {
+    if (list_Length(term_ArgumentList(Term))>2 ||
+	ren_NotPFactorOk(term_FirstArgument(Term)) ||
+	ren_NotPFactorOk(term_SecondArgument(Term)))
+      return TRUE;
+    else
+      return FALSE;
+  }
+  if (symbol_Equal(Top,fol_Implies())) {
+    if (ren_PFactorOk(term_FirstArgument(Term)) ||
+	ren_NotPFactorOk(term_SecondArgument(Term)))
+      return TRUE;
+    else
+      return FALSE;
+  }
+
+  if (symbol_Equal(Top,fol_And())) {
+    LIST Scan;
+    BOOL Ok;
+    Ok = FALSE;
+    for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+      if (ren_NotPFactorOk(list_Car(Scan))) {
+	if (Ok || ren_NotPExtraFactorOk(list_Car(Scan)))
+	  return TRUE; /* if two subterms with -p>1 or one subterm with -p>2 */
+	Ok = TRUE;
+      }
+  }
+
+  return FALSE; /* Either <Term> is a trivial conjunction or an atom */
+}
+
+
+static BOOL ren_NotPFactorOk(TERM Term)
+/**********************************************************
+  INPUT:   A term.
+  RETURNS: TRUE if transforming the term <Term> in negative polarity context
+           results in more than one clause.
+***********************************************************/
+{ 
+  SYMBOL Top;
+
+  /* if <Term> has the stamp, it will be renamed */
+  if (term_HasTermStamp(Term) || term_IsAtom(Term))
+    return FALSE;
+
+  Top = term_TopSymbol(Term);
+  
+  if (symbol_Equal(Top,fol_Equiv()) || symbol_Equal(Top,fol_Or()) ||
+      symbol_Equal(Top,fol_Implies()))
+    return TRUE;
+
+  if (symbol_Equal(Top,fol_Not()))
+    return ren_PFactorOk(term_FirstArgument(Term));
+
+  if (fol_IsQuantifier(Top))
+    return ren_NotPFactorOk(term_SecondArgument(Term));
+
+  if (symbol_Equal(Top,fol_And())) {
+    LIST Scan;
+    for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+      if (ren_NotPFactorOk(list_Car(Scan)))
+	return TRUE;
+  }
+
+  return FALSE; /* <Term> is a trivial conjunction */
+}
+
+
+static BOOL ren_PFactorBigger3(TERM Term)
+/**********************************************************
+  INPUT:   A term.
+  RETURNS: TRUE if transforming the term <Term> in positive
+           polarity context results in more than three clauses.
+***********************************************************/
+{
+  SYMBOL Top;
+  TERM   T1, T2;
+  LIST   Scan;
+  BOOL   Ok;
+
+  /* if <Term> has the stamp, it will be renamed */
+ if (term_HasTermStamp(Term) || term_IsAtom(Term))
+    return FALSE;
+
+  Top = term_TopSymbol(Term);
+
+  if (fol_IsQuantifier(Top))
+    return ren_PFactorBigger3(term_SecondArgument(Term));
+
+  if (symbol_Equal(Top, fol_Not()))
+    return ren_NotPFactorBigger3(term_FirstArgument(Term));
+
+  if (symbol_Equal(Top, fol_And())) {
+    unsigned char Limit;  /* invariant: p >= Limit */
+    Limit = list_Length(term_ArgumentList(Term));
+    for (Scan=term_ArgumentList(Term); !list_Empty(Scan) && Limit<=3;
+	 Scan=list_Cdr(Scan))
+      if (ren_PFactorOk(list_Car(Scan))) {
+	Limit++;
+	if (Limit<=3 && ren_PExtraFactorOk(list_Car(Scan))) {
+	  Limit++;
+	  if (Limit<=3 && ren_PFactorBigger3(list_Car(Scan)))
+	    Limit++;  /* works for unary conjunction, too */
+	}
+      }
+    return (Limit>3);
+  }
+  if (symbol_Equal(Top, fol_Or())) {
+    Ok = FALSE; /* is set to TRUE if a subterm with p factor >1 occurred */
+    for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+      if (ren_PFactorOk(list_Car(Scan))) {
+	if (Ok || ren_PFactorBigger3(list_Car(Scan)))
+	  return TRUE;  /* if two subterms with p>1 or one subterm with p>3 */
+	Ok = TRUE;
+      }
+    return FALSE;
+  }
+
+  T1 = term_FirstArgument(Term);
+  T2 = term_SecondArgument(Term);
+
+  if (symbol_Equal(Top, fol_Implies())) {
+    Ok = ren_PFactorOk(T2);
+    /* return TRUE if -p(T1)>3 || p(T2)>3 || (-p(T1)>1 && p(T2)>1) */
+    return ((ren_NotPFactorOk(T1) && (Ok || ren_NotPFactorBigger3(T1))) ||
+	    (Ok && ren_PFactorBigger3(T2)));
+  }
+  if (symbol_Equal(Top, fol_Equiv())) {
+    unsigned char T1Limit, T2Limit, NotT1Limit, NotT2Limit;
+    T1Limit    = ren_PFactorOk(T1)    ? 1 : 0;
+    NotT1Limit = ren_NotPFactorOk(T1) ? 1 : 0;
+    T2Limit    = ren_PFactorOk(T2)    ? 1 : 0;
+    NotT2Limit = ren_NotPFactorOk(T2) ? 1 : 0;
+    /* return TRUE, if p(T1)>2 || p(T2)>2 || -p(T1)>2 || -p(T2)>2 or at */
+    /* least two values out of { p(T1),p(T2),-p(T1),-p(T2) } are > 1    */
+    return ((T1Limit + NotT2Limit + NotT1Limit + T2Limit >= 2) ||
+	    (T1Limit!=0    && ren_PExtraFactorOk(T1)) ||
+	    (T2Limit!=0    && ren_PExtraFactorOk(T2)) ||
+	    (NotT1Limit!=0 && ren_NotPExtraFactorOk(T1)) ||
+	    (NotT2Limit!=0 && ren_NotPExtraFactorOk(T2)));
+  }
+  misc_StartErrorReport();
+  misc_ErrorReport(" \n In ren_PFactorBigger3: unknown first order operator.");
+  misc_FinishErrorReport();
+  return FALSE;
+}
+
+
+static BOOL ren_NotPFactorBigger3(TERM Term)
+/**********************************************************
+  INPUT:   A term.
+  RETURNS: TRUE if transforming the term <Term> in negative
+           polarity context results in more than three clauses.
+***********************************************************/
+{
+  SYMBOL Top;
+  TERM   T1, T2;
+  LIST   Scan;
+  BOOL   Ok;
+
+  /* if <Term> has the stamp, it will be renamed */
+  if (term_HasTermStamp(Term) || term_IsAtom(Term))
+    return FALSE;
+
+  Top = term_TopSymbol(Term);
+
+  if (fol_IsQuantifier(Top))
+    return ren_NotPFactorBigger3(term_SecondArgument(Term));
+
+  if (symbol_Equal(Top, fol_Not()))
+    return ren_PFactorBigger3(term_FirstArgument(Term));
+
+  if (symbol_Equal(Top, fol_Or())) {
+    unsigned char Limit;  /* invariant: -p >= Limit */
+    Limit = list_Length(term_ArgumentList(Term));
+    for (Scan=term_ArgumentList(Term); !list_Empty(Scan) && Limit<=3;
+	 Scan=list_Cdr(Scan))
+      if (ren_NotPFactorOk(list_Car(Scan))) {
+	Limit++;
+	if (Limit<=3 && ren_NotPExtraFactorOk(list_Car(Scan))) {
+	  Limit++;
+	  if (Limit<=3 && ren_NotPFactorBigger3(list_Car(Scan)))
+	    Limit++;  /* works for unary disjunction, too */
+	}
+      }
+    return (Limit>3);
+  }
+  if (symbol_Equal(Top, fol_And())) {
+    Ok = FALSE; /* is set to TRUE if a subterm with -p factor >1 occurred */
+    for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+      if (ren_NotPFactorOk(list_Car(Scan))) {
+	if (Ok || ren_NotPFactorBigger3(list_Car(Scan)))
+	  return TRUE; /* if two subterms with -p>1 or one subterm with -p>3 */
+	Ok = TRUE;
+      }
+    return FALSE;
+  }
+
+  T1 = term_FirstArgument(Term);
+  T2 = term_SecondArgument(Term);
+
+  if (symbol_Equal(Top, fol_Implies())) {
+    Ok = ren_NotPFactorOk(T2);
+    /* return TRUE if p(T1)>2 || -p(T2)>2 || (p(T1)>1 && -p(T2)>1) */
+    return ((ren_PFactorOk(T1) && (Ok || ren_PExtraFactorOk(T1))) ||
+	    (Ok && ren_NotPExtraFactorOk(T2)));
+  }
+  if (symbol_Equal(Top, fol_Equiv())) {
+    unsigned char T1Limit, T2Limit, NotT1Limit, NotT2Limit;
+    T1Limit    = ren_PFactorOk(T1)    ? 1 : 0;
+    NotT1Limit = ren_NotPFactorOk(T1) ? 1 : 0;
+    T2Limit    = ren_PFactorOk(T2)    ? 1 : 0;
+    NotT2Limit = ren_NotPFactorOk(T2) ? 1 : 0;
+    /* return TRUE, if p(T1)>2 || p(T2)>2 || -p(T1)>2 || -p(T2)>2 or at */
+    /* least two values out of { p(T1),p(T2),-p(T1),-p(T2) } are > 1    */
+    return ((T1Limit + NotT2Limit + NotT1Limit + T2Limit >= 2) ||
+	    (T1Limit!=0    && ren_PExtraFactorOk(T1)) ||
+	    (T2Limit!=0    && ren_PExtraFactorOk(T2)) ||
+	    (NotT1Limit!=0 && ren_NotPExtraFactorOk(T1)) ||
+	    (NotT2Limit!=0 && ren_NotPExtraFactorOk(T2)));
+  }
+  misc_StartErrorReport();
+  misc_ErrorReport(" \n In ren_NotPFactorBigger3: unknown first order operator.");
+  misc_FinishErrorReport();
+  return FALSE;
+}
+
+
+static BOOL ren_AFactorOk(TERM Term1, TERM Term2)
+/**********************************************************
+  INPUT:   Two terms where <Term1> is a superterm of <Term2>
+  RETURNS: TRUE if the A-Factor of Term2 in Term1 is larger than one.
+***********************************************************/
+{ 
+  SYMBOL Top;
+  TERM   Super;
+
+  if (Term1 == Term2)
+    return FALSE;
+
+  Super = term_Superterm(Term2);
+  Top   = term_TopSymbol(Super);    
+  
+  if (symbol_Equal(Top,fol_And()) || fol_IsQuantifier(Top))
+    return ren_AFactorOk(Term1, Super);
+
+  if (symbol_Equal(Top,fol_Not()))
+    return ren_BFactorOk(Term1, Super);
+
+  if (symbol_Equal(Top,fol_Or())) {
+    LIST Scan;
+    TERM Sub;
+    for (Scan=term_ArgumentList(Super);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+      Sub = (TERM)list_Car(Scan);
+      if (Sub != Term2 && ren_PFactorOk(Sub))
+	return TRUE;
+    }
+    return ren_AFactorOk(Term1, Super);
+  }
+
+  if (symbol_Equal(Top,fol_Implies())) {
+    if (Term2 == term_FirstArgument(Super))
+      return ren_BFactorOk(Term1, Super);
+    else
+      return (ren_NotPFactorOk(term_FirstArgument(Super)) || ren_AFactorOk(Term1, Super));
+  }
+  if (symbol_Equal(Top,fol_Equiv())) {
+    int Pol;
+    Pol = ren_Polarity(Super);
+    if (Pol == 0)
+      return TRUE;
+    if (Term2 == term_FirstArgument(Super))
+      Term2 = term_SecondArgument(Super);
+    else
+      Term2 = term_FirstArgument(Super);
+
+    if (Pol == 1)
+      return (ren_NotPFactorOk(Term2) || ren_AFactorOk(Term1,Super));
+    else
+      return (ren_PFactorOk(Term2) || ren_BFactorOk(Term1,Super));
+  }
+  misc_StartErrorReport();
+  misc_ErrorReport("In ren_AFactorOk: Unknown first order operator.");
+  misc_FinishErrorReport();
+  return FALSE; 
+}
+
+static BOOL ren_AExtraFactorOk(TERM Term1, TERM Term2)
+/**********************************************************
+  INPUT:   Two terms where <Term1> is a superterm of <Term2>
+  RETURNS: TRUE if the A-Factor of Term2 in Term1 is larger than two.
+***********************************************************/
+{ 
+  SYMBOL Top;
+  TERM   Super;
+  BOOL   Ok;
+
+  if (Term1 == Term2)
+    return FALSE;
+
+  Super = term_Superterm(Term2);
+  Top   = term_TopSymbol(Super);    
+  
+  if (symbol_Equal(Top,fol_And()) || fol_IsQuantifier(Top))
+    return ren_AExtraFactorOk(Term1, Super);
+
+  if (symbol_Equal(Top,fol_Not()))
+    return ren_BExtraFactorOk(Term1, Super);
+
+  if (symbol_Equal(Top,fol_Or())) {
+    LIST Scan;
+    TERM Sub;
+    Ok = FALSE;
+    for (Scan=term_ArgumentList(Super);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+      Sub = (TERM)list_Car(Scan);
+      if (Sub != Term2 && ren_PFactorOk(Sub)) {
+	if (Ok || ren_PExtraFactorOk(Sub))
+	  return TRUE;
+	Ok = TRUE;
+      }
+    }
+    /* return TRUE if (p>1 for one subterm and a>1) or a>2 */
+    return (ren_AFactorOk(Term1,Super) &&
+	    (Ok || ren_AExtraFactorOk(Term1, Super)));
+  }
+
+  if (symbol_Equal(Top,fol_Implies())) {
+    if (Term2 == term_FirstArgument(Super))
+      return ren_BExtraFactorOk(Term1, Super);
+    else {
+      TERM T1;
+      T1 = term_FirstArgument(Super);
+      Ok = ren_AFactorOk(Term1, Super);
+      /* return TRUE if (-p>1 and a>1) or -p>2 or a>2 */
+      return ((ren_NotPFactorOk(T1) && (Ok || ren_NotPExtraFactorOk(T1))) ||
+	      (Ok && ren_AExtraFactorOk(Term1,Super)));
+    }
+  }
+  if (symbol_Equal(Top,fol_Equiv())) {
+    if (Term2 == term_FirstArgument(Super))
+      Term2 = term_SecondArgument(Super);
+    else
+      Term2 = term_FirstArgument(Super);
+
+    switch (ren_Polarity(Super)) {
+    case 0:
+      return (ren_PFactorOk(Term2) ||  ren_NotPFactorOk(Term2) ||
+	      ren_AFactorOk(Term1,Super) ||  ren_BFactorOk(Term1,Super));
+    case 1:
+      Ok = ren_AFactorOk(Term1, Super);
+      return ((ren_NotPFactorOk(Term2) && (Ok || ren_NotPExtraFactorOk(Term2))) ||
+	      (Ok && ren_AExtraFactorOk(Term1,Super)));
+    case -1:
+      Ok = ren_BFactorOk(Term1, Super);
+      return ((ren_PFactorOk(Term2) && (Ok || ren_PExtraFactorOk(Term2))) ||
+	      (Ok && ren_BExtraFactorOk(Term1,Super)));
+    }
+  }
+  misc_StartErrorReport();
+  misc_ErrorReport("In ren_AExtraFactorOk: Unknown first order operator.");
+  misc_FinishErrorReport();
+  return FALSE; 
+}
+
+
+static BOOL ren_AFactorBigger3(TERM Term1, TERM Term2)
+/**********************************************************
+  INPUT:   Two terms where <Term1> is a superterm of <Term2>
+  RETURNS: TRUE if the A-Factor of Term2 in Term1 is larger than three.
+***********************************************************/
+{
+  TERM   Super;
+  SYMBOL Top;
+  BOOL   Ok;
+
+  if (Term1 == Term2)
+    return FALSE;
+
+  Super = term_Superterm(Term2);
+  Top   = term_TopSymbol(Super);    
+  
+  if (symbol_Equal(Top,fol_And()) || fol_IsQuantifier(Top))
+    return ren_AFactorBigger3(Term1, Super);
+
+  if (symbol_Equal(Top,fol_Not()))
+    return ren_BFactorBigger3(Term1, Super);
+
+  if (symbol_Equal(Top, fol_Or())) {
+    LIST Scan;
+    TERM Sub;
+    Ok = FALSE; /* is set to TRUE if a subterm with p factor >1 occurred */
+    for (Scan=term_ArgumentList(Super);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+      Sub = list_Car(Scan);
+      if (Term2 != Sub  && ren_PFactorOk(Sub)) {
+	if (Ok || ren_PFactorBigger3(Sub))
+	  return TRUE;  /* if two subterms with p>1 or one subterm with p>3 */
+	Ok = TRUE;
+      }
+    }
+    return (ren_AFactorOk(Term1, Super) &&
+	    (Ok || ren_AFactorBigger3(Term1, Super)));
+  }
+  if (symbol_Equal(Top,fol_Implies())) {
+    if (Term2 == term_FirstArgument(Super))
+      return ren_BFactorBigger3(Term1, Super);
+    else {
+      TERM T1;
+      T1 = term_FirstArgument(Super);
+      Ok = ren_AFactorOk(Term1, Super);
+      /* return TRUE if (-p>1 and a>1) or -p>3 or a>3 */
+      return ((ren_NotPFactorOk(T1) && (Ok || ren_NotPFactorBigger3(T1))) ||
+	      (Ok && ren_AFactorBigger3(Term1, Super)));
+    }
+  }
+  if (symbol_Equal(Top,fol_Equiv())) {
+    if (Term2 == term_FirstArgument(Super))
+      Term2 = term_SecondArgument(Super);
+    else
+      Term2 = term_FirstArgument(Super);
+
+    switch (ren_Polarity(Super)) {
+    case 0: {
+      unsigned ALimit, BLimit, PLimit, NotPLimit;
+      ALimit    = ren_AFactorOk(Term1, Super) ? 1 : 0;
+      BLimit    = ren_BFactorOk(Term1, Super) ? 1 : 0;
+      PLimit    = ren_PFactorOk(Term2)        ? 1 : 0;
+      NotPLimit = ren_NotPFactorOk(Term2)     ? 1 : 0;
+      /* return TRUE if a>2 || b>2 || p>2 || -p>2 or at least */
+      /* two values out of { a, b, p, -p } are > 1            */
+      return ((ALimit + BLimit + PLimit + NotPLimit >= 2) ||
+	      (PLimit!=0    && ren_PExtraFactorOk(Term2)) ||
+	      (NotPLimit!=0 && ren_NotPExtraFactorOk(Term2)) ||
+	      (ALimit!=0    && ren_AExtraFactorOk(Term1,Super)) ||
+	      (BLimit!=0    && ren_BExtraFactorOk(Term1,Super)));
+    }
+    case 1:
+      Ok = ren_AFactorOk(Term1, Super);
+      /* return TRUE if a>3 || -p>3 || (a>1 && -p>1) */
+      return ((ren_NotPFactorOk(Term2) && (Ok || ren_NotPFactorBigger3(Term2))) ||
+	      (Ok && ren_AFactorBigger3(Term1, Super)));
+    case -1:
+      Ok = ren_BFactorOk(Term1, Super);
+      /* return TRUE if b>3 || p>3 || (b>1 && p>1) */
+      return ((ren_PFactorOk(Term2) && (Ok || ren_PFactorBigger3(Term2))) ||
+	      (Ok && ren_BFactorBigger3(Term1, Super)));
+    }
+  }
+  misc_StartErrorReport();
+  misc_ErrorReport("In ren_AFactorBigger3: Unknown first order operator.");
+  misc_FinishErrorReport();
+  return FALSE; 
+}
+
+
+static BOOL ren_BFactorOk(TERM Term1, TERM Term2)
+/**********************************************************
+  INPUT:   Two terms where <Term1> is a superterm of <Term2>
+  RETURNS: TRUE if the B-Factor of Term2 in Term1 is larger than one.
+***********************************************************/
+{ 
+  SYMBOL Top;
+  TERM   Super;
+
+  if (Term1 == Term2)
+    return FALSE;
+
+  Super = term_Superterm(Term2);
+  Top   = term_TopSymbol(Super);    
+  
+  if (symbol_Equal(Top,fol_Or()) || fol_IsQuantifier(Top))
+    return ren_BFactorOk(Term1, Super);
+
+  if (symbol_Equal(Top,fol_Not()))
+    return ren_AFactorOk(Term1, Super);
+
+  if (symbol_Equal(Top,fol_And())) {
+    LIST Scan;
+    TERM Sub;
+    for (Scan=term_ArgumentList(Super);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+      Sub = (TERM)list_Car(Scan);
+      if (Sub != Term2 && ren_NotPFactorOk(Sub))
+	return TRUE;
+    }
+    return ren_BFactorOk(Term1, Super);
+  }
+
+  if (symbol_Equal(Top,fol_Implies())) {
+    if (Term2 == term_FirstArgument(Super))
+      return (ren_PFactorOk(term_SecondArgument(Super)) || ren_AFactorOk(Term1, Super));
+    else
+      return ren_BFactorOk(Term1, Super);
+  }
+  if (symbol_Equal(Top,fol_Equiv())) {
+    int Pol;
+    Pol = ren_Polarity(Super);
+    if (Pol == 0)
+      return TRUE;
+    if (Term2 == term_FirstArgument(Super))
+      Term2 = term_SecondArgument(Super);
+    else
+      Term2 = term_FirstArgument(Super);
+
+    if (Pol == 1)
+      return (ren_PFactorOk(Term2) || ren_AFactorOk(Term1,Super));
+    else
+      return (ren_NotPFactorOk(Term2) || ren_BFactorOk(Term1,Super));
+  }
+  misc_StartErrorReport();
+  misc_ErrorReport("In ren_BFactorOk: Unknown first order operator.");
+  misc_FinishErrorReport();
+  return FALSE; 
+}
+
+static BOOL ren_BExtraFactorOk(TERM Term1, TERM Term2)
+/**********************************************************
+  INPUT:   Two terms where <Term1> is a superterm of <Term2>
+  RETURNS: TRUE if the B-Factor of Term2 in Term1 is larger than two.
+***********************************************************/
+{ 
+  SYMBOL Top;
+  TERM   Super;
+  BOOL   Ok;
+
+  if (Term1 == Term2)
+    return FALSE;
+
+  Super = term_Superterm(Term2);
+  Top   = term_TopSymbol(Super);    
+  
+  if (symbol_Equal(Top,fol_Or()) || fol_IsQuantifier(Top))
+    return ren_BExtraFactorOk(Term1, Super);
+
+  if (symbol_Equal(Top,fol_Not()))
+    return ren_AExtraFactorOk(Term1, Super);
+
+  if (symbol_Equal(Top,fol_And())) {
+    LIST Scan;
+    TERM Sub;
+    Ok = FALSE;
+    for (Scan=term_ArgumentList(Super);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+      Sub = (TERM)list_Car(Scan);
+      if (Sub != Term2 && ren_NotPFactorOk(Sub)) {
+	if (Ok || ren_NotPExtraFactorOk(Sub))
+	  return TRUE;
+	Ok = TRUE;
+      }
+    }
+    /* return TRUE if (-p>1 for one subterm and b>1) or b>2 */
+    return (ren_BFactorOk(Term1,Super) &&
+	    (Ok || ren_BExtraFactorOk(Term1, Super)));
+  }
+
+  if (symbol_Equal(Top,fol_Implies())) {
+    if (Term2 == term_FirstArgument(Super)) {
+      TERM T2;
+      T2 = term_SecondArgument(Super);
+      Ok = ren_AFactorOk(Term1, Super);
+      /* return TRUE if (p>1 and a>1) or p>2 or a>2 */
+      return ((ren_PFactorOk(T2) && (Ok || ren_PExtraFactorOk(T2))) ||
+	      (Ok && ren_AExtraFactorOk(Term1, Super)));
+    }
+    else
+      return ren_BExtraFactorOk(Term1, Super);
+  }
+  if (symbol_Equal(Top,fol_Equiv())) {
+    if (Term2 == term_FirstArgument(Super))
+      Term2 = term_SecondArgument(Super);
+    else
+      Term2 = term_FirstArgument(Super);
+
+    switch (ren_Polarity(Super)) {
+    case 0:
+      return (ren_PFactorOk(Term2) ||  ren_NotPFactorOk(Term2) ||
+	      ren_AFactorOk(Term1,Super) ||  ren_BFactorOk(Term1,Super));
+    case 1:
+      Ok = ren_AFactorOk(Term1, Super);
+      return ((ren_PFactorOk(Term2) && (Ok || ren_PExtraFactorOk(Term2))) ||
+	      (Ok && ren_AExtraFactorOk(Term1,Super)));
+    case -1:
+      Ok = ren_BFactorOk(Term1, Super);
+      return ((ren_NotPFactorOk(Term2) && (Ok || ren_NotPExtraFactorOk(Term2))) ||
+	      (Ok && ren_BExtraFactorOk(Term1,Super)));
+    }
+  }
+  misc_StartErrorReport();
+  misc_ErrorReport("In ren_BExtraFactorOk: Unknown first order operator.");
+  misc_FinishErrorReport();
+  return FALSE; 
+}
+
+static BOOL ren_BFactorBigger3(TERM Term1, TERM Term2)
+/**********************************************************
+  INPUT:   Two terms where <Term1> is a superterm of <Term2>
+  RETURNS: TRUE if the B-Factor of Term2 in Term1 is larger than three.
+***********************************************************/
+{
+  TERM   Super;
+  SYMBOL Top;
+  BOOL   Ok;
+
+  if (Term1 == Term2)
+    return FALSE;
+
+ Super = term_Superterm(Term2);
+ Top   = term_TopSymbol(Super);
+ 
+  if (fol_IsQuantifier(Top) || symbol_Equal(Top, fol_Or()))
+    return ren_BFactorBigger3(Term1, Super);
+
+  if (symbol_Equal(Top, fol_Not()))
+    return ren_AFactorBigger3(Term1, Super);
+
+  if (symbol_Equal(Top, fol_And())) {
+    LIST Scan;
+    TERM Sub;
+    Ok = FALSE; /* is set to TRUE if a subterm with -p factor >1 occurred */
+    for (Scan=term_ArgumentList(Super);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+      Sub = list_Car(Scan);
+      if (Term2 != Sub  && ren_NotPFactorOk(Sub)) {
+	if (Ok || ren_NotPFactorBigger3(Sub))
+	  return TRUE; /* if two subterms with -p>1 or one subterm with -p>3 */
+	Ok = TRUE;
+      }
+    }
+    return (ren_BFactorOk(Term1, Super) &&
+	    (Ok || ren_BFactorBigger3(Term1, Super)));
+  }
+  if (symbol_Equal(Top,fol_Implies())) {
+    if (Term2 == term_FirstArgument(Super)) {
+      TERM T2;
+      T2 = term_SecondArgument(Super);
+      Ok = ren_AFactorOk(Term1, Super);
+      /* return TRUE if (p>1 and a>1) or p>3 or a>3 */
+      return ((ren_PFactorOk(T2) && (Ok || ren_PFactorBigger3(T2))) ||
+	      (Ok && ren_AFactorBigger3(Term1, Super)));
+    }
+    else
+      return ren_BFactorBigger3(Term1, Super);
+  }
+  if (symbol_Equal(Top,fol_Equiv())) {
+    if (Term2 == term_FirstArgument(Super))
+      Term2 = term_SecondArgument(Super);
+    else
+      Term2 = term_FirstArgument(Super);
+
+    switch (ren_Polarity(Super)) {
+    case 0: {
+      unsigned ALimit, BLimit, PLimit, NotPLimit;
+      ALimit    = ren_AFactorOk(Term1, Super) ? 1 : 0;
+      BLimit    = ren_BFactorOk(Term1, Super) ? 1 : 0;
+      PLimit    = ren_PFactorOk(Term2)        ? 1 : 0;
+      NotPLimit = ren_NotPFactorOk(Term2)     ? 1 : 0;
+      /* return TRUE if a>2 || b>2 || p>2 || -p>2 or at least */
+      /* two values out of { a, b, p, -p } are > 1            */
+      return ((ALimit + BLimit + PLimit + NotPLimit >= 2) ||
+	      (PLimit!=0    && ren_PExtraFactorOk(Term2)) ||
+	      (NotPLimit!=0 && ren_NotPExtraFactorOk(Term2)) ||
+	      (ALimit!=0    && ren_AExtraFactorOk(Term1,Super)) ||
+	      (BLimit!=0    && ren_BExtraFactorOk(Term1,Super)));
+    }
+    case 1:
+      Ok = ren_AFactorOk(Term1, Super);
+      /* return TRUE if a>3 || -p>3 || (a>1 && -p>1) */
+      return ((ren_PFactorOk(Term2) && (Ok || ren_PFactorBigger3(Term2))) ||
+	      (Ok && ren_AFactorBigger3(Term1, Super)));
+    case -1:
+      Ok = ren_BFactorOk(Term1, Super);
+      /* return TRUE if b>3 || p>3 || (b>1 && p>1) */
+      return ((ren_NotPFactorOk(Term2) && (Ok || ren_NotPFactorBigger3(Term2))) ||
+	      (Ok && ren_BFactorBigger3(Term1, Super)));
+    }
+  }
+  misc_StartErrorReport();
+  misc_ErrorReport("In ren_BFactorBigger3: Unknown first order operator.");
+  misc_FinishErrorReport();
+  return FALSE; 
+}
+
+
+static BOOL ren_HasBenefit(TERM Term1, TERM Term2, int Pol)
+/**********************************************************
+  INPUT:   Two terms and the polarity of the 2nd term in the overall formula.
+  RETURNS: TRUE if renaming <Term1> in <Term2> results in a positive benefit.
+  CAUTION: It is assumed that all superterms are set !
+***********************************************************/
+{ 
+  BOOL  PFacOk, NotPFacOk, AFacOk, BFacOk;
+  
+  switch (Pol) {
+    
+  case 0:
+    PFacOk    = ren_PFactorOk(Term2);
+    NotPFacOk = ren_NotPFactorOk(Term2);
+    AFacOk    = ren_AFactorOk(Term1,Term2);
+    BFacOk    = ren_BFactorOk(Term1,Term2);
+    return ((AFacOk && BFacOk && PFacOk && NotPFacOk) ||
+	    (AFacOk && PFacOk && (ren_PExtraFactorOk(Term2) || ren_AExtraFactorOk(Term1,Term2))) ||
+	    (BFacOk && NotPFacOk && (ren_NotPExtraFactorOk(Term2) || ren_BExtraFactorOk(Term1,Term2))));
+    break;
+
+  case 1:
+    return (ren_PFactorOk(Term2) && ren_AFactorOk(Term1,Term2));
+    break;
+
+  case -1:
+    return (ren_NotPFactorOk(Term2) && ren_BFactorOk(Term1,Term2));
+    break;
+  }
+  misc_StartErrorReport();
+  misc_ErrorReport("In ren_HasBenefit: Unknown polarity.");
+  misc_FinishErrorReport();
+  return FALSE;  
+}
+
+static BOOL ren_HasNonZeroBenefit(TERM Term1, int Pol1, TERM Term2, int Pol2)
+/**********************************************************
+  INPUT:   Two terms and the polarity of the terms in the overall formula.
+  RETURNS: TRUE if renaming <Term1> in <Term2> results in non-zero  positive benefit.
+  CAUTION: It is assumed that all superterms are set !
+***********************************************************/
+{ 
+  BOOL  PFacOk, NotPFacOk, AFacOk, BFacOk, PEFacOk, NotPEFacOk, AEFacOk, BEFacOk;
+  switch (Pol2) {
+  case 0:
+    PFacOk     = ren_PFactorOk(Term2);
+    NotPFacOk  = ren_NotPFactorOk(Term2);
+    AFacOk     = ren_AFactorOk(Term1,Term2);
+    BFacOk     = ren_BFactorOk(Term1,Term2);
+    PEFacOk    = PFacOk    && ren_PExtraFactorOk(Term2);
+    NotPEFacOk = NotPFacOk && ren_NotPExtraFactorOk(Term2);
+    AEFacOk    = AFacOk    && ren_AExtraFactorOk(Term1,Term2);
+    BEFacOk    = BFacOk    && ren_BExtraFactorOk(Term1,Term2);
+    
+    return ((AFacOk && BFacOk && PFacOk && NotPFacOk && (AEFacOk || BEFacOk || PEFacOk || NotPEFacOk)) || 
+	    (PEFacOk && AEFacOk) || (NotPEFacOk && BEFacOk) ||
+	    (AFacOk    && ren_PFactorBigger3(Term2)) ||
+	    (BFacOk    && ren_NotPFactorBigger3(Term2)) ||
+	    (PFacOk    && ren_AFactorBigger3(Term1, Term2)) ||
+	    (NotPFacOk && ren_BFactorBigger3(Term1, Term2)) ||
+	    /* The following conditions don't imply benefit > 0, but allow */
+	    /* some additional renamings with benefit 0.                   */
+	    (Pol1 == 0 && (symbol_Equal(term_TopSymbol(Term2),fol_Equiv()) ||
+			   ren_HasNEquivFathers(Term1,Term2,1))) ||
+	    ren_HasNEquivFathers(Term1,Term2,2));
+    break;
+
+  case 1:
+    /* return TRUE if (p>1 && a>2) || (p>2 && a>1) */
+    AFacOk = ren_AFactorOk(Term1,Term2);
+    return ((ren_PFactorOk(Term2) && (AFacOk || ren_AFactorOk(Term1,Term2))) ||
+	    (AFacOk && ren_AExtraFactorOk(Term1,Term2)));
+    break;
+
+  case -1:
+    /* return TRUE if (-p>1 && b>2) || (-p>2 && b>1) */
+    BFacOk = ren_BFactorOk(Term1,Term2);
+    return ((ren_NotPFactorOk(Term2) && (BFacOk || ren_NotPExtraFactorOk(Term2))) ||
+	    (BFacOk && ren_BExtraFactorOk(Term1,Term2)));
+    break;
+  }
+  misc_StartErrorReport();
+  misc_ErrorReport("In ren_HasNonZeroBenefit: Unknown polarity.");
+  misc_FinishErrorReport();
+  return FALSE;  
+}
+
+
+static LIST ren_GetRenamings(TERM Term1, TERM Term2, int Pol) 
+/**********************************************************
+  INPUT:   Two terms and the polarity of the 2nd term in the overall formula.
+  RETURNS: The list of subterms below <Term2> that have a positive renaming
+           benefit.
+  EFFECT:  All renamed formulae are stamped.
+***********************************************************/
+{ 
+  SYMBOL Top;
+  LIST   Result,Scan;
+
+  Result = list_Nil();
+
+  /* Don't rename formulae starting with "not" */
+  while (symbol_Equal(term_TopSymbol(Term2), fol_Not())) {
+    Term2 = term_FirstArgument(Term2);
+    Pol = -Pol;
+  }
+
+  if (term_IsAtom(Term2))
+    return Result;
+
+  Top = term_TopSymbol(Term2);
+
+  /* Don't rename arguments of a quantifier */
+  if (term_Superterm(Term2) &&
+      !fol_IsQuantifier(term_TopSymbol(term_Superterm(Term2))) &&
+      ren_HasBenefit(Term1, Term2, Pol)) {
+    Result = list_Cons(Term2,Result);
+    term_SetTermStamp(Term2);
+    Term1 = Term2;
+  }
+
+  if (fol_IsQuantifier(Top))
+    Result = list_Nconc(Result,ren_GetRenamings(Term1, term_SecondArgument(Term2), Pol));
+  else if (symbol_Equal(Top,fol_And()) || symbol_Equal(Top,fol_Or()))
+    for (Scan=term_ArgumentList(Term2);!list_Empty(Scan);Scan=list_Cdr(Scan))
+      Result = list_Nconc(Result,ren_GetRenamings(Term1,list_Car(Scan),Pol));
+  else if (symbol_Equal(Top,fol_Implies())) {
+    Result = list_Nconc(Result,ren_GetRenamings(Term1,term_FirstArgument(Term2),-Pol));
+    Result = list_Nconc(Result,ren_GetRenamings(Term1,term_SecondArgument(Term2),Pol));
+  } else if (symbol_Equal(Top,fol_Equiv())) {
+    Result = list_Nconc(Result, ren_GetRenamings(Term1,term_FirstArgument(Term2),0));
+    Result = list_Nconc(Result, ren_GetRenamings(Term1,term_SecondArgument(Term2),0));
+  } else {
+    misc_StartErrorReport();
+    misc_ErrorReport("In ren_GetRenamings: Unknown first-order operator.");
+    misc_FinishErrorReport();
+  }
+
+  return Result;
+}
+
+static int ren_Polarity(TERM Term)
+/**********************************************************
+  INPUT:   A term where the existence of superterms is assumed!.
+  RETURNS: The polarity of Term with respect to its superterms.
+***********************************************************/
+{
+  TERM SuperTerm;
+
+  SuperTerm = term_Superterm(Term);
+
+  if (SuperTerm) {
+    SYMBOL Top;
+    Top = term_TopSymbol(SuperTerm);
+    if (symbol_Equal(Top,fol_And()) || symbol_Equal(Top,fol_Or()) ||
+	fol_IsQuantifier(Top))
+      return ren_Polarity(SuperTerm);
+    if (symbol_Equal(Top,fol_Not()))
+      return (-ren_Polarity(SuperTerm));
+    if (symbol_Equal(Top,fol_Equiv()))
+      return 0;
+    if (symbol_Equal(Top,fol_Implies())) {
+      if (Term == term_FirstArgument(SuperTerm))
+	return (-ren_Polarity(SuperTerm));
+      else
+	return ren_Polarity(SuperTerm);
+    }
+    misc_StartErrorReport();
+    misc_ErrorReport("In ren_Polarity: Unknown first-order operator.");
+    misc_FinishErrorReport();
+  }
+
+  return 1;
+}
+
+
+static LIST ren_RemoveTerm(TERM Term, LIST Renamings)
+/**********************************************************
+  INPUT:   A formula and a list of renamings.
+  RETURNS: The renaming list where  <Term> is removed from
+           the renamings.
+  CAUTION: The list and the renamings are destructively changed.
+***********************************************************/
+{
+  LIST     Scan;
+  RENAMING Renaming;
+
+  /* Remove the Term from all renamings. In case the Hit term equals <Term> */
+  /* turn the renaming into a general renaming */
+  for (Scan=Renamings;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Renaming = (RENAMING)list_Car(Scan);
+    if (ren_Hit(Renaming) == Term) {
+      if (list_Empty(ren_Matches(Renaming))) {
+	ren_Delete(Renaming);
+	list_Rplaca(Scan, NULL);
+      }
+      else 
+	ren_SetGeneral(Renaming, TRUE);
+    }
+    else
+      ren_SetMatches(Renaming, list_PointerDeleteElement(ren_Matches(Renaming), Term));
+  }
+  
+  /* Take care for the NULL pointers */
+  Renamings = list_PointerDeleteElement(Renamings, NULL);
+
+  return Renamings;
+}
+
+static LIST ren_RemoveAllSubterms(TERM Term, LIST Renamings)
+/**********************************************************
+  INPUT:   A formula and a list of renamings.
+  RETURNS: The renaming list where  <Term> and all its subterms are
+           removed from the renamings.
+  CAUTION: The list and the renamings are destructively changed.
+***********************************************************/
+{
+  Renamings = ren_RemoveTerm(Term, Renamings);
+  
+  if (!symbol_IsPredicate(term_TopSymbol(Term))) {
+    if (fol_IsQuantifier(term_TopSymbol(Term)))
+      Renamings = ren_RemoveAllSubterms(term_SecondArgument(Term), Renamings);
+    else {
+      LIST Scan;
+      for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+	Renamings = ren_RemoveAllSubterms(list_Car(Scan), Renamings);
+    }
+  }
+
+  return Renamings;
+}
+
+
+
+static LIST ren_SolveDependencies(LIST Renamings)
+/**********************************************************
+  INPUT:   A list of renamings sorted by depth of the hits.
+  RETURNS: The renaming list where dependences are solved, i.e., if
+           a formula occurs in the matches of some renaming, then
+	   all its subterms are removed from other renamings, since
+	   the formulae of additional matches completely disappear
+	   after application of the renaming.
+           In case a subterm is the hit of another renaming but this
+           renaming has further matches, the further matches are turned
+           into new individual renamings.
+  CAUTION: The list and the renamings are destructively changed.
+***********************************************************/
+{
+  LIST     Scan;
+  RENAMING Renaming;
+  TERM     ActMatch;
+
+  if (list_Empty(Renamings))
+    return Renamings;
+
+  Renaming = (RENAMING)list_Car(Renamings);
+  for (Scan=ren_Matches(Renaming);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    ActMatch = (TERM)list_Car(Scan);
+    list_Rplacd(Renamings, ren_RemoveAllSubterms(ActMatch, list_Cdr(Renamings)));
+  }
+  list_Rplacd(Renamings, ren_SolveDependencies(list_Cdr(Renamings)));
+
+  return Renamings;
+}
+
+
+static TERM ren_FormulaRename(TERM Term, LIST Renamings, PRECEDENCE Precedence,
+			      LIST *SkolemSymbols) 
+/**********************************************************
+  INPUT:   A term and a list of renamings where all
+           dependencies between the renaming terms are
+	   solved and a precedence.
+  RETURNS: The renamed formula with respect to the renaming
+           list and all newly introduced Skolem symbols for
+	   renamings are added to <SkolemSymbols>.
+  EFFECT:  New Skolem predicates are created, and their precedence
+           is set in <Precedence>.
+  CAUTION: The formula <Term> is destructively changed.
+           The renamings are destructively changed.
+***********************************************************/
+{
+  TERM     Result,ActTerm,Hit,DefTerm,Superterm,NewTerm;
+  LIST     Scan,FreeVariables,Args,AllMatches;
+  SYMBOL   ActSymbol;
+  RENAMING Renaming;
+ 
+  DefTerm    = (TERM)NULL;
+  AllMatches = list_Nil();
+
+  if (!list_Empty(Renamings))
+    Result = term_Create(fol_And(),list_List(Term));
+  else
+    return Term;
+
+  ActSymbol = 0;
+
+  while (!list_Empty(Renamings)) {
+
+    Renaming       = (RENAMING)list_Car(Renamings); 
+    Renamings      = list_Cdr(Renamings);
+    Hit            = ren_Hit(Renaming);
+    Superterm      = term_Superterm(Hit);
+    FreeVariables  = fol_FreeVariables(Hit);
+    ActSymbol      = symbol_CreateSkolemPredicate(list_Length(FreeVariables),
+						  Precedence);
+    *SkolemSymbols = list_Cons((POINTER)ActSymbol,*SkolemSymbols);
+
+    /* printf("\n");fol_PrettyPrintDFG(ren_Hit(Renaming));printf("\n");*/
+
+    /* Install Definition */
+    if (ren_General(Renaming))     /* for general renamings the hit formula will be eventually deleted */
+      Hit = term_Copy(Hit);
+    NewTerm = term_Create(ActSymbol, term_CopyTermList(FreeVariables));
+    switch (ren_OverallPolarity(Renaming)) {
+    case 0:
+      DefTerm = term_Create(fol_Equiv(),list_Cons(term_Copy(NewTerm),list_List(Hit)));
+      break;
+	  
+    case 1:
+      DefTerm = term_Create(fol_Implies(),list_Cons(term_Copy(NewTerm),list_List(Hit)));
+      break;
+	  
+    case -1:
+      DefTerm = term_Create(fol_Implies(),list_Cons(Hit,list_List(term_Copy(NewTerm))));
+      break;
+    }
+    term_RplacSuperterm(term_FirstArgument(DefTerm),DefTerm);
+    term_RplacSuperterm(term_SecondArgument(DefTerm),DefTerm);
+    if (!list_Empty(FreeVariables))
+      DefTerm = fol_CreateQuantifier(fol_All(), term_CopyTermList(FreeVariables),
+				     list_List(DefTerm));
+    term_RplacArgumentList(Result,list_Nconc(term_ArgumentList(Result),list_List(DefTerm)));
+
+    /* Replace hit if renaming is not general */
+    if (!ren_General(Renaming)) {
+      term_RplacSuperterm(NewTerm, Superterm);
+      for (Args=term_ArgumentList(Superterm);!list_Empty(Args); Args=list_Cdr(Args)) 
+	if ((TERM)list_Car(Args) == Hit) {
+	  list_Rplaca(Args, NewTerm);
+	  break;
+	}    
+    }
+    else
+      term_Delete(NewTerm);
+
+
+    for (Scan=ren_Matches(Renaming); !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+      
+      ActTerm   = (TERM)list_Car(Scan);
+      Superterm = term_Superterm(ActTerm);
+
+      /* Always make new predicate term */
+      NewTerm   = term_Create(ActSymbol, term_CopyTermList(FreeVariables));
+      /* Bind the variables correctly */
+      /*puts("\n"); fol_PrettyPrintDFG(Result);
+	printf("\n Hit:\n"); term_PrettyPrint(Hit);
+	printf("\n ActTerm:\n"); term_PrettyPrint(ActTerm); printf("\n");*/
+      cont_StartBinding();
+      if (unify_MatchFlexible(cont_LeftContext(), Hit, ActTerm))
+	cont_ApplyBindingsModuloMatching(cont_LeftContext(), NewTerm, TRUE);
+      else {
+	misc_StartErrorReport();
+	misc_ErrorReport("\n In ren_FormulaRename: Further match is no instance of hit.\n");
+	misc_FinishErrorReport();
+      }
+      cont_BackTrack();
+
+      /* Now replace match */
+      term_RplacSuperterm(NewTerm, Superterm);
+      for (Args=term_ArgumentList(Superterm);!list_Empty(Args); Args=list_Cdr(Args)) 
+	if (list_Car(Args) == ActTerm) {
+	  list_Rplaca(Args, NewTerm);
+	  break;
+	}  
+    }
+    AllMatches = list_Nconc(ren_Matches(Renaming), AllMatches); /* Delete later due to dependencies */
+    ren_SetMatches(Renaming, list_Nil());
+    list_Delete(FreeVariables);
+  }
+  list_DeleteWithElement(AllMatches, (void (*)(POINTER)) term_Delete);
+  return Result;			   
+}
+
+static LIST ren_FreeRenaming(LIST Renamings)
+/**********************************************************
+  INPUT:   A list of  renamings.
+  RETURNS: The list of candidates without renamings that have
+           benefit zero.
+  CAUTION: Destructive.
+***********************************************************/
+{
+  LIST     Scan;
+  TERM     Father, Term;
+  RENAMING Candidate;
+
+  for (Scan=Renamings;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Candidate = (RENAMING)list_Car(Scan);
+    if (list_Empty(ren_Matches(Candidate))) {
+      Term   = ren_Hit(Candidate);
+      Father = term_Superterm(Term);
+      while (!term_HasTermStamp(Father) && term_Superterm(Father)) {
+	Father = term_Superterm(Father);
+      }
+	
+      term_ResetTermStamp(Term); /* Needed for P-Factor check */
+      if (ren_General(Candidate) ||                                /* a general renaming without matches is useless */
+	  !ren_HasNonZeroBenefit(Father, ren_Polarity(Father),  
+				 Term, ren_OverallPolarity(Candidate))) {
+	ren_Delete(Candidate);
+	list_Rplaca(Scan,NULL);
+      } else {
+	/* Term will be renamed */
+	term_SetTermStamp(Term); /* Undo temporary change */
+      }
+    }
+  }
+
+  Renamings = list_PointerDeleteElement(Renamings,NULL);
+
+  return Renamings;
+}
+
+static LIST ren_FurtherMatches(TERM Formula, LIST Formulas)
+/**********************************************************
+  INPUT:   A formula and a list of formulas that are candidates
+           for renaming inside the formula.
+  RETURNS: A list of renamings where additional matches of
+           the already found formulas in <Formula> are considered.
+	   First the most general formula <Hit> of any renaming inside
+	   <Formula> is computed, then all instances of <Hit> inside
+	   <Formula> built the actual renaming.
+	   No formula occurs twice in the resulting renamings.
+***********************************************************/
+{
+  LIST Scan1, Scan2, Allmatches, Matchables, Renamings;
+  TERM Hit;
+  int  Polarity, NewPol;
+
+  Allmatches = list_Nil();
+  Renamings  = list_Nil();
+
+  for (Scan1=Formulas; !list_Empty(Scan1); Scan1=list_Cdr(Scan1)) {
+    Hit = (TERM)list_Car(Scan1);
+
+    if (!list_PointerMember(Allmatches, Hit)) {
+      Matchables = list_Cons(Hit, fol_Generalizations(Formula, Hit));
+      Hit        = fol_MostGeneralFormula(Matchables); /* Could be further improved: construct it ! */
+      list_Delete(Matchables);
+
+      if (!list_PointerMember(Allmatches, Hit)) {  /* Potentially <Hit> is now different */
+	Allmatches = list_Cons(Hit,Allmatches);
+	Matchables = fol_Instances(Formula, Hit);
+	Polarity   = ren_Polarity(Hit);
+	
+	for (Scan2=Matchables; !list_Empty(Scan2); Scan2=list_Cdr(Scan2)) {
+	  if (list_PointerMember(Allmatches, list_Car(Scan2)))
+	    list_Rplaca(Scan2, NULL);
+	  else {
+	    NewPol = ren_Polarity(list_Car(Scan2));
+	    if (NewPol != Polarity)
+	      Polarity = 0;
+	  }
+	}
+	Matchables = list_PointerDeleteElement(Matchables, NULL);
+	Allmatches = list_Nconc(list_Copy(Matchables), Allmatches);
+	Renamings  = list_Cons(ren_Create(Hit, Matchables, Polarity),Renamings);
+      }
+    }
+  }
+  list_Delete(Allmatches);
+
+  return Renamings;
+}
+
+
+TERM ren_Rename(TERM Term, PRECEDENCE Precedence, LIST *SkolemSymbols,
+		BOOL Document, BOOL Match)
+/**********************************************************
+  INPUT:   A term, a precedence, a pointer to a list of
+           Skolem symbols, a flag indicating whether the
+	   renamings should be documented and a flag
+	   indicating whether matching subterms should be
+	   renamed using the same predicate.
+  RETURNS: The possibly changed Term where subformulae are renamed
+           if this results in a smaller clause normal form, with
+	   respect to the number of clauses. The newly introduced
+	   Skolem predicates are added to <SkolemSymbols>.
+	   The precedence of the new symbols is set in <Precedence>.
+  CAUTION: Formulae are changed destructively.
+           This function expects that both conjunctions and disjunction
+	   have at least two arguments!
+***********************************************************/
+{
+  LIST Renamings, Scan, Formulas;
+
+  Renamings = list_Nil();
+  Formulas  = list_Nil();
+
+  if (term_StampOverflow(ren_STAMPID))
+    ren_ResetTermStamp(Term);
+
+#ifdef CHECK
+  fol_CheckFatherLinks(Term);
+#endif
+
+  term_StartStamp();
+
+  Formulas = ren_GetRenamings(Term, Term, 1);
+
+  /* Formulas = list_GreaterNumberSort(Formulas, (NAT (*)(POINTER)) fol_Depth); */
+
+  if (Match)
+    Renamings = ren_FurtherMatches(Term, Formulas);
+  else {
+    for (Scan=Formulas;!list_Empty(Scan);Scan=list_Cdr(Scan))
+      Renamings = list_Cons(ren_Create(list_Car(Scan),list_Nil(),ren_Polarity(list_Car(Scan))),Renamings);
+  }
+
+  Renamings = ren_FreeRenaming(Renamings);
+
+  Renamings = list_Sort(Renamings, (BOOL (*) (POINTER, POINTER))ren_RootDistanceSmaller);   
+                                                       /* for dependencies sort renamings top down */
+
+  Renamings = ren_SolveDependencies(Renamings);  /* dependencies in further matches */
+
+  Renamings = ren_FreeRenaming(Renamings); /* possibly depency solving has created non-zero benefit renamings */
+
+  if (!list_Empty(Renamings) && Document) {
+    puts("\n\n\t Renaming term:");
+    fol_PrettyPrintDFG(Term);
+    for (Scan=Renamings;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+      puts("\n");
+      ren_PrettyPrint((RENAMING)list_Car(Scan));
+    }
+    puts("\n");
+  }
+
+  Term = ren_FormulaRename(Term, Renamings, Precedence, SkolemSymbols);
+  
+  if (!list_Empty(Renamings) && Document) {
+    puts("\n\n\t Renamed term:");
+    fol_PrettyPrintDFG(Term);
+    puts("\n");
+  }
+
+  list_DeleteWithElement(Renamings, (void (*)(POINTER)) ren_Delete);
+  list_Delete(Formulas);
+
+  term_StopStamp();
+
+  return Term;
+}
+
+void ren_PrettyPrint(RENAMING Ren)
+/**********************************************************
+  INPUT:   A renaming.
+  EFFECT:  pretty prints the renaming to <stdout>
+***********************************************************/
+{
+  LIST Matches;
+
+  puts("\t Renaming:");
+  puts("\n\t ========= \n");
+  fol_PrettyPrintDFG(ren_Hit(Ren));
+  puts("\n\n\t Instances:");
+  for (Matches=ren_Matches(Ren); !list_Empty(Matches); Matches=list_Cdr(Matches)) {
+    fol_PrettyPrintDFG(list_Car(Matches));
+    puts("\n");
+  }
+  printf("\n\t Polarity: %d\n", ren_OverallPolarity(Ren));
+  printf("\n\t General : %d\n", (ren_General(Ren) ? 1 : 0));
+}
diff --git a/test/spass/renaming.h b/test/spass/renaming.h
new file mode 100644
index 0000000000000000000000000000000000000000..663363e3005ebd105bcf645b2357f3066f290d6b
--- /dev/null
+++ b/test/spass/renaming.h
@@ -0,0 +1,168 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                   RENAMING                             * */
+/* *                                                        * */
+/* *  $Module:   REN                                        * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 2000, 2001            * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#ifndef _SPASS_RENAMING_
+#define _SPASS_RENAMING_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "misc.h"
+#include "foldfg.h"
+#include "unify.h"
+#include "vector.h"
+
+/**************************************************************/
+/* Data Structures and Constants                              */
+/**************************************************************/
+
+typedef struct {
+  TERM   hit;
+  LIST   matches;
+  BOOL   general;
+  int    polarity;
+} *RENAMING, RENAMING_NODE;
+
+/* <hit>       is the formula that has a positive benefit              */
+/* <matches>   are further matches of <hit> in the overall formula     */
+/* <general>   is TRUE iff the <hit> formula must not be replaced but  */
+/*             is a generalzation of the matches formulae that are to  */
+/*             be replaced                                             */
+/* <polarity>  is the most general polarity of <hit> and all <matches> */
+
+ 
+/**************************************************************/
+/* Functions                                                 */
+/**************************************************************/
+
+
+static __inline__ int ren_OverallPolarity(RENAMING ren)
+{
+  return ren->polarity;
+}
+
+static __inline__ TERM ren_Hit(RENAMING ren)
+{
+  return ren->hit;
+}
+
+static __inline__ LIST ren_Matches(RENAMING ren)
+{
+  return ren->matches;
+}
+
+static __inline__ BOOL ren_General(RENAMING ren)
+{
+  return ren->general;
+}
+
+static __inline__ void ren_SetMatches(RENAMING ren, LIST matches)
+{
+  ren->matches = matches;
+}
+
+static __inline__ void ren_SetHit(RENAMING ren, TERM hit)
+{
+  ren->hit = hit;
+}
+
+static __inline__ void ren_SetOverallPolarity(RENAMING ren, int polarity)
+{
+  ren->polarity = polarity;
+}
+
+static __inline__ void ren_SetGeneral(RENAMING ren, BOOL general)
+{
+  ren->general = general;
+}
+
+
+
+static __inline__ RENAMING ren_Create(TERM hit, LIST matches, int polarity)
+/**************************************************************
+  INPUT:   A formula, a list of further matching formulae
+           and the overall polarity of the <hit> and the further <matches>.
+  RETURNS: A new renaming object, which is initialized.
+           General is set to false.
+  MEMORY:  Allocates memory for the RENAMING.
+***************************************************************/
+{
+  RENAMING Result;
+
+  Result           = (RENAMING)memory_Malloc(sizeof(RENAMING_NODE));
+  Result->hit      = hit;
+  Result->matches  = matches;
+  Result->polarity = polarity;
+  Result->general  = FALSE;
+
+  return Result;
+}
+
+static __inline__ void ren_Delete(RENAMING ren)
+/**************************************************************
+  INPUT:   A renaming.
+  RETURNS: void.
+  MEMORY:  Frees memory for the RENAMING and the matches list.
+           Formulae are not deleted.
+***************************************************************/
+{
+  list_Delete(ren->matches);
+  memory_Free(ren,sizeof(RENAMING_NODE));
+}
+
+
+/**************************************************************/
+/* Function Prototypes                                        */
+/**************************************************************/
+
+void ren_Init(void);
+TERM ren_Rename(TERM, PRECEDENCE, LIST*,BOOL, BOOL);
+void ren_PrettyPrint(RENAMING);
+
+#endif
diff --git a/test/spass/resolution.c b/test/spass/resolution.c
new file mode 100644
index 0000000000000000000000000000000000000000..96e4bff580338831db6573160a210b0c15f276c5
--- /dev/null
+++ b/test/spass/resolution.c
@@ -0,0 +1,178 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                RESOLUTION                              * */
+/* *                                                        * */
+/* *  $Module:   RESOLUTION                                 * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 2001                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "resolution.h"
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+
+void res_InsertClauseIndex(CLAUSE clause, st_INDEX stindex)
+/**********************************************************
+  INPUT:   A st_INDEX and a clause.
+  RETURNS: Inserts the clause in the st_INDEX stindex.
+  CAUTION: None.
+***********************************************************/
+{
+  int n,j;
+
+  n = clause_Length(clause);
+  for (j = 0; j < n; j++)
+    st_EntryCreate(stindex,
+		   clause_GetLiteral(clause,j),
+		   clause_GetLiteralTerm(clause,j),
+		   cont_LeftContext());
+}
+
+
+void res_DeleteClauseIndex(CLAUSE clause, st_INDEX stindex)
+/**********************************************************
+  INPUT:   A st_INDEX and a clause.
+  RETURNS: Deletes the clause from the st_INDEX stindex.
+  CAUTION: None.
+***********************************************************/
+{
+  int n, j;
+
+  n = clause_Length(clause);
+  for (j = 0; j < n; j++)
+    if (!st_EntryDelete(stindex,
+			clause_GetLiteral(clause,j), 
+			clause_GetLiteralTerm(clause,j),
+			cont_LeftContext()))
+      misc_DumpCore();
+}
+
+
+
+CLAUSE res_SelectLightestClause(LIST clauselist)
+/**********************************************************
+  INPUT:   A list of clauses.
+  RETURNS: The lightest clause of the clauselist. 
+  CAUTION: None.
+***********************************************************/
+{
+  CLAUSE clause;
+  LIST   scan;
+  int    min;
+
+  clause = list_Car(clauselist);
+  min    = clause_Weight(clause);
+  
+  for (scan=list_Cdr(clauselist); !list_Empty(scan); scan=list_Cdr(scan)) {
+    if (clause_Weight(list_Car(scan)) < min) {
+      clause = list_Car(scan);
+      min    = clause_Weight(clause);
+    }
+  }
+  return clause;
+}
+
+
+BOOL res_HasTautology(CLAUSE clause)
+/**********************************************************
+  INPUT:   A clauses.
+  RETURNS: TRUE if the clause contains a complementary 
+           literal pair and FALSE otherwise. 
+  CAUTION: None.
+***********************************************************/
+{
+  BOOL found;
+  TERM literal1;
+  int  i, j, n;
+
+  found = FALSE;
+  n     = clause_Length(clause);
+  
+  for (i = 0; i < n && !found; i++) {
+    literal1 = fol_ComplementaryTerm(clause_GetLiteralTerm(clause,i));
+    for (j = 0; j < n && !found; j++)
+      if (j != i && term_Equal(literal1, clause_GetLiteralTerm(clause,j)))
+	found = TRUE;
+
+    term_Delete(literal1);
+  }
+  return found;
+}
+
+
+
+BOOL res_BackSubWithLength(CLAUSE clause, st_INDEX stindex)
+/**********************************************************
+  INPUT:   A clauses and an index.
+  RETURNS: TRUE if a clause of the index subsumes the clause clause
+           and length(clause) >= length(clause of index).
+  CAUTION: None.
+***********************************************************/
+{
+  int     n,i; 
+  LIST    scan,generals;
+  TERM    term;
+  LITERAL litres;
+
+  n = clause_Length(clause);
+  for (i = 0; i < n; i++) {
+    term      = clause_GetLiteralTerm(clause,i);
+    generals  = st_GetGen(cont_LeftContext(), stindex, term);
+    for (scan = generals; !list_Empty(scan); scan = list_Cdr(scan)) {
+      litres = (LITERAL) list_Car(scan);
+      if (litres == clause_GetLiteral(clause_LiteralOwningClause(litres),0) &&
+	  clause_Length(clause) >= clause_Length(clause_LiteralOwningClause(litres)) &&
+	  clause_Weight(clause) >= clause_Weight(clause_LiteralOwningClause(litres)) &&
+	  subs_Idc(clause_LiteralOwningClause(litres),clause)) {
+	    list_Delete(generals);
+	    return TRUE;
+      }
+    }
+    list_Delete(generals);
+  }
+  return FALSE;
+}
+
+
diff --git a/test/spass/resolution.h b/test/spass/resolution.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b29779091a50db01d7782769bf60501fbe3883e
--- /dev/null
+++ b/test/spass/resolution.h
@@ -0,0 +1,73 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                RESOLUTION                              * */
+/* *                                                        * */
+/* *  $Module:   RESOLUTION                                 * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1998, 2001 MPI fuer Informatik    * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* $RCSfile$ */
+
+#ifndef _RESOLUTION_
+#define _RESOLUTION_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "misc.h"
+#include "unify.h"
+#include "symbol.h"
+#include "foldfg.h"
+#include "st.h"
+#include "subsumption.h"
+#include "condensing.h"
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+
+void    res_InsertClauseIndex(CLAUSE, st_INDEX); /* used by cnf */
+void    res_DeleteClauseIndex(CLAUSE, st_INDEX); /* used by cnf */
+CLAUSE  res_SelectLightestClause(LIST);          /* used by cnf */
+BOOL    res_BackSubWithLength(CLAUSE, st_INDEX); /* used by cnf */
+BOOL    res_HasTautology(CLAUSE);                /* used by cnf */
+
+#endif
diff --git a/test/spass/rpos.c b/test/spass/rpos.c
new file mode 100644
index 0000000000000000000000000000000000000000..edd1b8b702063de9db607560b407c7f4a8baf3d2
--- /dev/null
+++ b/test/spass/rpos.c
@@ -0,0 +1,521 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *         RECURSIVE PATH ORDERING WITH STATUS            * */
+/* *                                                        * */
+/* *  $Module:   RPOS                                       * */
+/* *                                                        * */
+/* *  Copyright (C) 1997, 1998, 1999, 2000, 2001            * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+     
+/* $RCSfile$ */
+
+#include "rpos.h"
+
+
+/**************************************************************/
+/* Top Down Version                                           */
+/**************************************************************/
+
+static LIST rpos_MultisetDifference(TERM T1, TERM T2)
+/**************************************************************
+  INPUT:   Two terms.
+  RETURNS: The multiset difference between the arguments
+           of both terms with respect to rpos_Equal.
+***************************************************************/
+{
+  LIST result;
+
+  result = list_Copy(term_ArgumentList(T1));
+  result = list_NMultisetDifference(result, term_ArgumentList(T2),
+				    (BOOL (*)(POINTER,POINTER)) rpos_Equal);
+  return result;
+}
+  
+  
+static ord_RESULT rpos_MulGreaterEqual(TERM T1, TERM T2)
+/**************************************************************
+  INPUT:   Two terms with equal top symbols and multiset status.
+  RETURNS: ord_GREATER_THAN if <T1> is greater than <T2>,
+	   ord_EQUAL        if both terms are equal and
+	   ord_UNCOMPARABLE otherwise.
+***************************************************************/
+{
+  LIST l1, l2;
+
+  l1 = rpos_MultisetDifference(T1, T2);
+  if (list_Empty(l1))
+    /* If |M| = |N| and M-N = {} then N-M = {} */ 
+    return ord_Equal();   /* Terms are equal */
+  else {
+    LIST scan;
+    BOOL greater;
+
+    l2 = rpos_MultisetDifference(T2, T1);
+
+    for (greater = TRUE; !list_Empty(l2) && greater; l2 = list_Pop(l2)) {
+      for (scan = l1, greater = FALSE; !list_Empty(scan) && !greater; scan = list_Cdr(scan))
+	greater = rpos_Greater(list_Car(scan), list_Car(l2));
+    }
+    list_Delete(l1); /* l2 was freed in the outer for loop */
+    if (greater)
+      return ord_GreaterThan();
+    else
+      return ord_Uncomparable();
+  }
+}
+
+static ord_RESULT rpos_LexGreaterEqual(TERM T1, TERM T2)
+/**************************************************************
+  INPUT:   Two terms with equal top symbols and lexicographic status.
+  RETURNS: ord_GREATER_THAN if <T1> is greater than <T2>,
+	   ord_EQUAL        if both terms are equal and 
+	   ord_UNCOMPARABLE otherwise.
+***************************************************************/
+{
+  ord_RESULT result;
+  LIST       l1, l2, scan1, scan2;
+
+  if (symbol_HasProperty(term_TopSymbol(T1), ORDRIGHT)) {
+    l1 = list_Reverse(term_ArgumentList(T1)); /* Create new lists */
+    l2 = list_Reverse(term_ArgumentList(T2));
+  } else {
+    l1 = term_ArgumentList(T1);
+    l2 = term_ArgumentList(T2);
+  }
+  /* First ignore equal arguments */
+  result = ord_Equal();
+  for (scan1 = l1, scan2 = l2; !list_Empty(scan1);
+       scan1 = list_Cdr(scan1), scan2 = list_Cdr(scan2)) {
+    result = rpos_GreaterEqual(list_Car(scan1), list_Car(scan2));
+    if (!ord_IsEqual(result))
+      break;
+  }
+
+  if (ord_IsEqual(result))  /* All arguments are equal, so the terms */
+    /* empty */;            /* are equal with respect to RPOS */
+  else if (ord_IsGreaterThan(result)) {
+    /* Check if T1 > each remaining argument of T2 */
+    for (scan2 = list_Cdr(scan2); !list_Empty(scan2) && rpos_Greater(T1, list_Car(scan2));
+	 scan2 = list_Cdr(scan2)); /* Empty body */
+    if (list_Empty(scan2))
+      result = ord_GreaterThan();
+    else
+      result = ord_Uncomparable();
+  }
+  else {
+    /* Argument of T1 was not >= argument of T2. */
+
+    /* Try to find an argument of T1 that is >= T2 */
+    for (scan1 = list_Cdr(scan1), result = ord_Uncomparable();
+	 !list_Empty(scan1) && !ord_IsGreaterThan(result);
+	 scan1 = list_Cdr(scan1)) {
+      if (!ord_IsUncomparable(rpos_GreaterEqual(list_Car(scan1), T2)))
+	result = ord_GreaterThan();
+    }
+  }
+
+  if (symbol_HasProperty(term_TopSymbol(T1), ORDRIGHT)) {
+    list_Delete(l1);  /* Delete the lists create above */
+    list_Delete(l2);
+  }
+  return result;
+}
+
+
+BOOL rpos_Equal(TERM T1, TERM T2)
+/**************************************************************
+  INPUT:   Two terms.
+  RETURNS: TRUE, if <T1> is equal to <T2> and
+           FALSE otherwise.
+***************************************************************/
+{
+  LIST l1, l2;
+
+  if (!term_EqualTopSymbols(T1, T2))
+    return FALSE;
+  else if (!term_IsComplex(T1))  /* Equal variable or constant */
+    return TRUE;
+  else {
+    if (symbol_HasProperty(term_TopSymbol(T1), ORDMUL)) {  /* MUL case */
+      l1 = rpos_MultisetDifference(T1, T2);
+      if (list_Empty(l1))
+	return TRUE;
+      else {
+	list_Delete(l1);
+	return FALSE;
+      }
+    } else {   /* LEX case */
+      for (l1 = term_ArgumentList(T1), l2 = term_ArgumentList(T2);
+	   !list_Empty(l1) &&  rpos_Equal(list_Car(l1), list_Car(l2));
+	   l1 = list_Cdr(l1), l2 = list_Cdr(l2))
+	/* empty */;
+      return list_Empty(l1);  /* All arguments were equal */
+    }
+  }
+}
+
+
+ord_RESULT rpos_GreaterEqual(TERM T1, TERM T2)
+/**************************************************************
+  INPUT:   Two terms.
+  RETURNS: ord_GREATER_THAN if <T1> is greater than <T2>
+	   ord_EQUAL        if both terms are equal
+	   ord_UNCOMPARABLE otherwise.
+  CAUTION: The precedence from the order module is used to determine
+           the precedence of symbols!
+***************************************************************/
+{
+  LIST scan;
+
+  if (term_IsVariable(T1)) {
+    if (term_EqualTopSymbols(T1, T2))
+      return ord_Equal();   /* T2 is the same variable */
+    else
+      /* A variable can't be greater than another term */
+      return ord_Uncomparable();
+  } else if (term_IsVariable(T2)) {   /* T1 isn't a variable */
+    if (term_ContainsSymbol(T1, term_TopSymbol(T2)))
+      return ord_GreaterThan();
+    else
+      return ord_Uncomparable();
+  } else if (term_EqualTopSymbols(T1, T2)) {
+    if (symbol_HasProperty(term_TopSymbol(T1), ORDMUL))
+      return rpos_MulGreaterEqual(T1, T2);
+    else
+      return rpos_LexGreaterEqual(T1, T2);
+  } else {
+    if (symbol_PrecedenceGreater(ord_PRECEDENCE, term_TopSymbol(T1),
+				 term_TopSymbol(T2))) {
+      /* Different top symbols, symbol of T1 > symbol of T2. */
+      /* Try if T1 > each argument of T2.                    */
+      for (scan = term_ArgumentList(T2); !list_Empty(scan); scan = list_Cdr(scan))
+	if (!rpos_Greater(T1,  list_Car(scan)))
+	  return ord_Uncomparable();
+      return ord_GreaterThan();
+    } else {
+      /* Try to find an argument of T1 that is >= T2 */
+      for (scan = term_ArgumentList(T1); !list_Empty(scan); scan = list_Cdr(scan))
+	if (!ord_IsUncomparable(rpos_GreaterEqual(list_Car(scan), T2)))
+	  return ord_GreaterThan();    /* Argument of T1 >= T2 */
+      return ord_Uncomparable();
+    }
+  }
+}
+
+ord_RESULT rpos_Compare(TERM T1, TERM T2)
+/**************************************************************
+  INPUT:   Two terms.
+  RETURNS: The relation between the two terms with respect to the
+           RPOS ordering:
+           ord_GREATER_THAN if <T1> is greater than <T2>,
+	   ord_EQUAL        if both terms are equal,
+           ord_SMALLER_THAN if <T2> is greater than <T1> and
+	   ord_UNCOMPARABLE otherwise.
+  CAUTION: The precedence from the order module is used to determine
+           the precedence of symbols!
+***************************************************************/
+{
+  ord_RESULT result;
+
+  result = rpos_GreaterEqual(T1, T2);
+  if (!ord_IsUncomparable(result))
+    return result;
+  else if (rpos_Greater(T2, T1))
+    return ord_SmallerThan();
+  else
+    return ord_UNCOMPARABLE;
+}
+
+/**************************************************************/
+/* Term comparison with respect to bindings                   */
+/**************************************************************/
+
+static LIST rpos_ContMultisetDifference(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2)
+/**************************************************************
+  INPUT:   Two contexts and two terms.
+  RETURNS: The multiset difference between the arguments
+           of both terms with respect to rpos_ContEqual.
+  EFFECT:  Variable bindings are considered.
+***************************************************************/
+{
+  LIST result, scan1, scan2;
+
+  /* Don't apply bindings at top level, since that happened */
+  /* in rpos_ContGreaterEqual */
+
+  /* We can't use list_NMultisetDifference, since that function   */
+  /* expects an equality functions for terms that takes two terms */
+  /* as arguments. We also need the two contexts resolve variable */
+  /* bindings. */
+  result = list_Copy(term_ArgumentList(T1));
+  for (scan2 = term_ArgumentList(T2); !list_Empty(scan2);
+       scan2 = list_Cdr(scan2)) {
+    /* Delete at most one occurrence of the */
+    /* current element of list2 from list1 */
+    for (scan1 = result; !list_Empty(scan1); scan1 = list_Cdr(scan1)) {
+      if (list_Car(scan1) != NULL &&
+	  rpos_ContEqual(C1, list_Car(scan1), C2, list_Car(scan2))) {
+	/* arg of list1 wasn't deleted earlier and terms are equal */
+	list_Rplaca(scan1, NULL);  /* Mark argument of T1 as deleted */
+	break;
+      }
+    }
+  }
+  return list_PointerDeleteElement(result, NULL); /* Delete all marked terms */
+}
+  
+  
+static ord_RESULT rpos_ContMulGreaterEqual(CONTEXT C1, TERM T1,
+					   CONTEXT C2, TERM T2)
+/**************************************************************
+  INPUT:   Two contexts and two terms with equal top symbols
+           and multiset status.
+  RETURNS: ord_GREATER_THAN if <T1> is greater than <T2>,
+	   ord_EQUAL        if both terms are equal and
+	   ord_UNCOMPARABLE otherwise.
+  EFFECT:  Variable bindings are considered.
+***************************************************************/
+{
+  LIST l1, l2;
+
+  /* Don't apply bindings at top level, since that happened */
+  /* in rpos_ContGreaterEqual. */
+
+  l1 = rpos_ContMultisetDifference(C1, T1, C2, T2);
+  if (list_Empty(l1))
+    /* If |M| = |N| and M-N = {} then N-M = {} */ 
+    return ord_Equal();   /* Terms are equal */
+  else {
+    LIST scan;
+    BOOL greater;
+
+    l2 = rpos_ContMultisetDifference(C2, T2, C1, T1);
+
+    for (greater = TRUE; !list_Empty(l2) && greater; l2 = list_Pop(l2)) {
+      for (scan = l1, greater = FALSE; !list_Empty(scan) && !greater;
+	   scan = list_Cdr(scan))
+	greater = rpos_ContGreater(C1, list_Car(scan), C2, list_Car(l2));
+    }
+    list_Delete(l1); /* l2 was freed in the outer for loop */
+    if (greater)
+      return ord_GreaterThan();
+    else
+      return ord_Uncomparable();
+  }
+}
+
+static ord_RESULT rpos_ContLexGreaterEqual(CONTEXT C1, TERM T1,
+					   CONTEXT C2, TERM T2)
+/**************************************************************
+  INPUT:   Two contexts and two terms with equal top symbols
+           and lexicographic status.
+  RETURNS: ord_GREATER_THAN if <T1> is greater than <T2>,
+	   ord_EQUAL        if both terms are equal and 
+	   ord_UNCOMPARABLE otherwise.
+  EFFECT:  Variable bindings are considered.
+***************************************************************/
+{
+  ord_RESULT result;
+  LIST       l1, l2, scan1, scan2;
+
+  /* Don't apply bindings at top level, since that happened */
+  /* in rpos_ContGreaterEqual */
+
+  if (symbol_HasProperty(term_TopSymbol(T1), ORDRIGHT)) {
+    l1 = list_Reverse(term_ArgumentList(T1)); /* Create new lists */
+    l2 = list_Reverse(term_ArgumentList(T2));
+  } else {
+    l1 = term_ArgumentList(T1);
+    l2 = term_ArgumentList(T2);
+  }
+  /* First ignore equal arguments */
+  result = ord_Equal();
+  for (scan1 = l1, scan2 = l2; !list_Empty(scan1);
+       scan1 = list_Cdr(scan1), scan2 = list_Cdr(scan2)) {
+    result = rpos_ContGreaterEqual(C1, list_Car(scan1), C2, list_Car(scan2));
+    if (!ord_IsEqual(result))
+      break;
+  }
+
+  if (ord_IsEqual(result))  /* All arguments are equal, so the terms */
+    /* empty */;            /* are equal with respect to RPOS */
+  else if (ord_IsGreaterThan(result)) {
+    /* Check if T1 > each remaining argument of T2 */
+    for (scan2 = list_Cdr(scan2);
+	 !list_Empty(scan2) && rpos_ContGreater(C1, T1, C2, list_Car(scan2));
+	 scan2 = list_Cdr(scan2)); /* Empty body */
+    if (list_Empty(scan2))
+      result = ord_GreaterThan();
+    else
+      result = ord_Uncomparable();
+  }
+  else {
+    /* Argument of T1 was not >= argument of T2. */
+    /* Try to find an argument of T1 that is >= T2 */
+    for (scan1 = list_Cdr(scan1), result = ord_Uncomparable();
+	 !list_Empty(scan1) && !ord_IsGreaterThan(result);
+	 scan1 = list_Cdr(scan1)) {
+      if (!ord_IsUncomparable(rpos_ContGreaterEqual(C1,list_Car(scan1),C2,T2)))
+	result = ord_GreaterThan();
+    }
+  }
+
+  if (symbol_HasProperty(term_TopSymbol(T1), ORDRIGHT)) {
+    list_Delete(l1);  /* Delete the lists create above */
+    list_Delete(l2);
+  }
+  return result;
+}
+
+
+BOOL rpos_ContEqual(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2)
+/**************************************************************
+  INPUT:   Two contexts and two terms.
+  RETURNS: TRUE, if <T1> is equal to <T2> and
+           FALSE otherwise.
+  EFFECT:  Variable bindings are considered.
+***************************************************************/
+{
+  LIST l1, l2;
+
+  T1 = cont_Deref(&C1, T1);
+  T2 = cont_Deref(&C2, T2);
+
+  if (!term_EqualTopSymbols(T1, T2))
+    return FALSE;
+  else if (!term_IsComplex(T1))
+    return TRUE;
+  else {
+    if (symbol_HasProperty(term_TopSymbol(T1), ORDMUL)) {
+      l1 = rpos_ContMultisetDifference(C1, T1, C2, T2);
+      if (list_Empty(l1))
+	return TRUE;
+      else {
+	list_Delete(l1);
+	return FALSE;
+      }
+    } else {   /* LEX case */
+      for (l1 = term_ArgumentList(T1), l2 = term_ArgumentList(T2);
+	   !list_Empty(l1) &&  rpos_ContEqual(C1,list_Car(l1),C2,list_Car(l2));
+	   l1 = list_Cdr(l1), l2 = list_Cdr(l2)); /* empty body */
+      return list_Empty(l1);  /* All arguments were equal */
+    }
+  }
+}
+
+
+ord_RESULT rpos_ContGreaterEqual(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2)
+/**************************************************************
+  INPUT:   Two contexts and two terms.
+  RETURNS: ord_GREATER_THAN if <T1> is greater than <T2>
+	   ord_EQUAL        if both terms are equal
+	   ord_UNCOMPARABLE otherwise.
+  EFFECT:  Variable bindings are considered.
+  CAUTION: The precedence from the order module is used to determine
+           the precedence of symbols!
+***************************************************************/
+{
+  LIST scan;
+
+  T1 = cont_Deref(&C1, T1);
+  T2 = cont_Deref(&C2, T2);
+
+  if (term_IsVariable(T1)) {
+    if (term_EqualTopSymbols(T1, T2))
+      return ord_Equal();   /* T2 is the same variable */
+    else
+      /* A variable can't be greater than another term */
+      return ord_Uncomparable();
+  } else if (term_IsVariable(T2)) {   /* T1 isn't a variable */
+    if (cont_TermContainsSymbol(C1, T1, term_TopSymbol(T2)))
+      return ord_GreaterThan();
+    else
+      return ord_Uncomparable();
+  } else if (term_EqualTopSymbols(T1, T2)) {
+    if (symbol_HasProperty(term_TopSymbol(T1), ORDMUL))
+      return rpos_ContMulGreaterEqual(C1, T1, C2, T2);
+    else
+      return rpos_ContLexGreaterEqual(C1, T1, C2, T2);
+  } else {
+    if (symbol_PrecedenceGreater(ord_PRECEDENCE, term_TopSymbol(T1),
+				 term_TopSymbol(T2))) {
+      /* Different top symbols, symbol of T1 > symbol of T2. */
+      /* Try if T1 > each argument of T2.                    */
+      for (scan = term_ArgumentList(T2); !list_Empty(scan); scan = list_Cdr(scan))
+	if (!rpos_ContGreater(C1, T1, C2, list_Car(scan)))
+	  return ord_Uncomparable();
+      return ord_GreaterThan();
+    } else {
+      /* Try to find an argument of T1 that is >= T2 */
+      for (scan = term_ArgumentList(T1); !list_Empty(scan); scan = list_Cdr(scan))
+	if (!ord_IsUncomparable(rpos_ContGreaterEqual(C1,list_Car(scan),C2,T2)))
+	  return ord_GreaterThan();    /* Argument of T1 >= T2 */
+      return ord_Uncomparable();
+    }
+  }
+}
+
+ord_RESULT rpos_ContCompare(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2)
+/**************************************************************
+  INPUT:   Two contexts and two terms.
+  RETURNS: The relation between the two terms with respect to the
+           RPOS ordering:
+           ord_GREATER_THAN if <T1> is greater than <T2>,
+	   ord_EQUAL        if both terms are equal,
+           ord_SMALLER_THAN if <T2> is greater than <T1> and
+	   ord_UNCOMPARABLE otherwise.
+  EFFECT:  Variable bindings are considered.
+  CAUTION: The precedence from the order module is used to determine
+           the precedence of symbols!
+***************************************************************/
+{
+  ord_RESULT result;
+
+  T1 = cont_Deref(&C1, T1);
+  T2 = cont_Deref(&C2, T2);
+
+  result = rpos_ContGreaterEqual(C1, T1, C2, T2);
+  if (!ord_IsUncomparable(result))
+    return result;
+  else if (rpos_ContGreater(C2, T2, C1, T1))
+    return ord_SmallerThan();
+  else
+    return ord_UNCOMPARABLE;
+}
+  
diff --git a/test/spass/rpos.h b/test/spass/rpos.h
new file mode 100644
index 0000000000000000000000000000000000000000..6cef9e86998777595f2c24ca724d9a9c2a535057
--- /dev/null
+++ b/test/spass/rpos.h
@@ -0,0 +1,82 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *         RECURSIVE PATH ORDERING WITH STATUS            * */
+/* *                                                        * */
+/* *  $Module:   RPOS                                       * */
+/* *                                                        * */
+/* *  Copyright (C) 1997, 1998 MPI fuer Informatik          * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _RPOS_
+#define _RPOS_
+
+#include "misc.h"
+#include "term.h"
+#include "order.h"
+#include "context.h"
+
+/**************************************************************/
+/*  Function Prototypes                                       */
+/**************************************************************/
+
+BOOL       rpos_Equal(TERM, TERM);
+ord_RESULT rpos_GreaterEqual(TERM, TERM);
+ord_RESULT rpos_Compare(TERM, TERM);
+
+BOOL       rpos_ContEqual(CONTEXT, TERM, CONTEXT, TERM);
+ord_RESULT rpos_ContGreaterEqual(CONTEXT, TERM, CONTEXT, TERM);
+ord_RESULT rpos_ContCompare(CONTEXT, TERM, CONTEXT, TERM);
+
+/**************************************************************/
+/*  Inline Functions                                          */
+/**************************************************************/
+
+static __inline__ BOOL rpos_Greater(TERM T1, TERM T2)
+{
+  return ord_IsGreaterThan(rpos_GreaterEqual(T1, T2));
+}
+
+static __inline__ BOOL rpos_ContGreater(CONTEXT C1, TERM T1,
+					CONTEXT C2, TERM T2)
+{
+  return ord_IsGreaterThan(rpos_ContGreaterEqual(C1, T1, C2, T2));
+}
+
+#endif
diff --git a/test/spass/rules-inf.c b/test/spass/rules-inf.c
new file mode 100644
index 0000000000000000000000000000000000000000..38bbaa6ba469c92757ae02c326acf7b7daac3a21
--- /dev/null
+++ b/test/spass/rules-inf.c
@@ -0,0 +1,4281 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                INFERENCE RULES                         * */
+/* *                                                        * */
+/* *  $Module:   INFRULES                                   * */
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "rules-inf.h"
+
+
+/**************************************************************/
+/* Some auxiliary functions for testing postconditions        */
+/**************************************************************/
+
+static BOOL inf_LitMax(CLAUSE Clause, int i, int j, SUBST Subst, BOOL Strict,
+		       FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, the index of a maximal literal, another 
+           literal index, a substitution, a boolean flag, a 
+	   flag store and a precedence.
+  RETURNS: If <Strict>=FALSE the function returns TRUE iff the
+           literal at index <i> is still maximal in the 
+	   instantiated clause.
+	   If <Strict>=TRUE the function returns TRUE iff the
+	   literal is STRICTLY maximal in the instantiated 
+	   clause. The literal at index j is omitted at literal 
+	   comparison.
+	   However, setting j to a negative number ensures that
+	   all literals are compared with the literal at 
+	   index <i>.
+  CAUTION: DON'T call this function with a clause with selected
+           literals!
+***************************************************************/
+{
+  TERM       Max, LitTerm;
+  LITERAL    Lit;
+  ord_RESULT Compare;
+  int        k, l;
+
+#ifdef CHECK
+  if (!clause_LiteralIsMaximal(clause_GetLiteral(Clause, i)) ||
+      (Strict &&
+       !clause_LiteralGetFlag(clause_GetLiteral(Clause, i), STRICTMAXIMAL))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_LitMax: Literal %d isn't %smaximal.",
+		     i, Strict ? "strictly " : "");
+    misc_FinishErrorReport();
+  }
+  if (i < clause_FirstAntecedentLitIndex(Clause) ||
+      i > clause_LastSuccedentLitIndex(Clause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_LitMax: Literal index %d is out of range.", i);
+    misc_FinishErrorReport();
+  }
+  /* If literal <i> is selected, there's no need to check for maximality, */
+  /* if <i> isn't selected, but there're other literals selected,         */
+  /* inferences with literal <i> are forbidden.                           */ 
+  if (clause_GetFlag(Clause, CLAUSESELECT)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_LitMax: There're selected literals.", i);
+    misc_FinishErrorReport();
+  }    
+#endif
+
+  Lit = clause_GetLiteral(Clause, i);
+  /* Check necessary condition */
+  if (!clause_LiteralIsMaximal(Lit) ||
+      (Strict && !clause_LiteralGetFlag(Lit, STRICTMAXIMAL)))
+    return FALSE;
+  /* Only antecedent and succedent literals are compared, so if there's */
+  /* only one such literal, it's maximal.                               */
+  /* If the substitution is empty, the necessary condition tested above */
+  /* is sufficient, too.                                                */
+  if ((clause_NumOfAnteLits(Clause) + clause_NumOfSuccLits(Clause) == 1) ||
+      subst_Empty(Subst))
+    return TRUE;
+
+  l   = clause_LastSuccedentLitIndex(Clause);
+  Max = subst_Apply(Subst,term_Copy(clause_GetLiteralTerm(Clause,i)));
+
+  for (k = clause_FirstAntecedentLitIndex(Clause); k <= l; k++)
+    if (k != i && k != j &&
+	clause_LiteralIsMaximal(clause_GetLiteral(Clause, k))) {
+      /* Only compare with maximal literals, since for every non-maximal */
+      /* literal, there's at least one maximal literal, that is bigger.  */
+      LitTerm = subst_Apply(Subst,term_Copy(clause_GetLiteralTerm(Clause,k)));
+      Compare = ord_LiteralCompare(Max,
+				   clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i)),
+				   LitTerm,
+				   clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,k)),
+				   TRUE, Flags, Precedence);
+      if (Compare == ord_SmallerThan() || (Strict && Compare == ord_Equal())) {
+	term_Delete(Max);
+	term_Delete(LitTerm);
+	return FALSE;
+      }
+      term_Delete(LitTerm);
+    }
+  term_Delete(Max);
+
+  return TRUE;
+}
+
+
+static BOOL inf_LiteralsMax(CLAUSE Clause, int i, SUBST Subst,
+			    CLAUSE PartnerClause, int j, SUBST PartnerSubst,
+			    FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   The parents of a resolution inference, the respective
+           literal indices and substitutions, a flag store and 
+	   a precedence.
+  RETURNS: TRUE iff the positive/negative literals are still
+           strictly maximal/maximal in the instantiated clause.
+	   If a negative literal is selected, no comparison
+	   is made.
+***************************************************************/
+{
+#ifdef CHECK
+  if ((clause_GetFlag(Clause, CLAUSESELECT) &&
+       !clause_LiteralGetFlag(clause_GetLiteral(Clause,i),LITSELECT)) ||
+      (clause_GetFlag(PartnerClause, CLAUSESELECT) &&
+       !clause_LiteralGetFlag(clause_GetLiteral(PartnerClause,j),LITSELECT))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_LiteralsMax: Another literal is selected.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (!clause_GetFlag(Clause, CLAUSESELECT) &&
+      !inf_LitMax(Clause,i,-1,Subst,
+		  i>clause_LastAntecedentLitIndex(Clause),Flags, Precedence))
+    return FALSE;
+  if (!clause_GetFlag(PartnerClause, CLAUSESELECT) &&
+      !inf_LitMax(PartnerClause,j,-1,PartnerSubst,
+		  j>clause_LastAntecedentLitIndex(PartnerClause), Flags, Precedence))
+    return FALSE;
+
+  return TRUE;
+}
+
+
+static BOOL inf_LitMaxWith2Subst(CLAUSE Clause, int i, int j, SUBST Subst2,
+				 SUBST Subst1, BOOL Strict, FLAGSTORE Flags,
+				 PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, the index of a maximal literal, another 
+           literal index, two substitutions, a boolean flag, 
+	   a flag store and a precedence.
+  RETURNS: In contrast to the function inf_LitMax this function 
+           compares the literals with respect to the composition 
+	   of the two substitutions Subst2 ° Subst1.
+	   If <Strict>=FALSE the function returns TRUE iff the
+           literal at index <i> is still maximal in the 
+	   instantiated clause.
+	   If <Strict>=TRUE the function returns TRUE iff the
+	   literal is STRICTLY maximal in the instantiated 
+	   clause.
+	   The literal at index j is omitted at literal 
+	   comparison.
+	   However, setting j to a negative number ensures that
+	   all literals are compared with the literal at 
+	   index <i>.
+  CAUTION: DON'T call this function with a clause with selected
+           literals!
+***************************************************************/
+{
+  TERM       Max, LitTerm;
+  LITERAL    Lit;
+  ord_RESULT Compare;
+  int        k, l;
+
+#ifdef CHECK
+  if (!clause_LiteralIsMaximal(clause_GetLiteral(Clause, i)) ||
+      (Strict &&
+       !clause_LiteralGetFlag(clause_GetLiteral(Clause, i), STRICTMAXIMAL))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_LitMaxWith2Subst: Literal %d isn't %smaximal.",
+		     i, Strict ? "strictly " : "");
+    misc_FinishErrorReport();
+  }
+  if (i < clause_FirstAntecedentLitIndex(Clause) ||
+      i > clause_LastSuccedentLitIndex(Clause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_LitMaxWith2Subst: Literal index %d is out of range.", i);
+    misc_FinishErrorReport();
+  }
+  /* If literal <i> is selected, there's no need to check for maximality, */
+  /* if <i> isn't selected, but there're other literals selected,         */
+  /* inferences with literal <i> are forbidden.                           */ 
+  if (clause_GetFlag(Clause, CLAUSESELECT)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_LitMaxWith2Subst: There're selected literals.", i);
+    misc_FinishErrorReport();
+  }    
+#endif
+
+  Lit = clause_GetLiteral(Clause, i);
+  /* Check necessary condition */
+  if (!clause_LiteralIsMaximal(Lit) ||
+      (Strict && !clause_LiteralGetFlag(Lit, STRICTMAXIMAL)))
+    return FALSE;
+  /* Only antecedent and succedent literals are compared, so if there's    */
+  /* only one such literal, it's maximal.                                  */
+  /* If both substitutions are empty, the necessary condition tested above */
+  /* is sufficient, too.                                                   */
+  if ((clause_NumOfAnteLits(Clause) + clause_NumOfSuccLits(Clause) == 1) ||
+      (subst_Empty(Subst1) && subst_Empty(Subst2)))
+    return TRUE;
+
+  l   = clause_LastSuccedentLitIndex(Clause);
+  Max = subst_Apply(Subst1, term_Copy(clause_GetLiteralTerm(Clause,i)));
+  Max = subst_Apply(Subst2, Max);
+
+  for (k = clause_FirstAntecedentLitIndex(Clause); k <= l; k++)
+    if (k != i && k != j &&
+	clause_LiteralIsMaximal(clause_GetLiteral(Clause, k))) {
+      /* Only compare with maximal literals, since for every non-maximal */
+      /* literal, there's at least one maximal literal, that is bigger.  */
+      LitTerm = subst_Apply(Subst1,term_Copy(clause_GetLiteralTerm(Clause,k)));
+      LitTerm = subst_Apply(Subst2, LitTerm);
+      Compare = ord_LiteralCompare(Max,
+				   clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i)),
+				   LitTerm,
+				   clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,k)),
+				   TRUE, Flags, Precedence);
+      if (Compare == ord_SmallerThan() || (Strict && Compare == ord_Equal())) {
+	term_Delete(Max);
+	term_Delete(LitTerm);
+	return FALSE;
+      }
+      term_Delete(LitTerm);
+    }
+  term_Delete(Max);
+
+  return TRUE;
+}
+
+
+static BOOL inf_LiteralsMaxWith2Subst(CLAUSE Clause, int i, CLAUSE PartnerClause,
+				      int j, SUBST Subst2, SUBST Subst1,
+				      FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   The parents of a resolution inference, the 
+           respective literal indices and substitutions, a 
+	   flag store and a precedence.
+  RETURNS: In contrast to the function inf_LiteralsMax
+           the composition Subst2 ° Subst1 is applied to both
+	   clauses.
+	   The function returns TRUE iff the positive/negative 
+	   literals are still strictly maximal/maximal in the 
+	   instantiated clause.
+	   If a negative literal is selected, no comparison
+	   is made.
+***************************************************************/
+{
+#ifdef CHECK
+  if ((clause_GetFlag(Clause, CLAUSESELECT) &&
+       !clause_LiteralGetFlag(clause_GetLiteral(Clause,i),LITSELECT)) ||
+      (clause_GetFlag(PartnerClause, CLAUSESELECT) &&
+       !clause_LiteralGetFlag(clause_GetLiteral(PartnerClause,j),LITSELECT))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_LiteralsMaxWith2Subst: Another literal is selected.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (!clause_GetFlag(Clause, CLAUSESELECT) &&
+      !inf_LitMaxWith2Subst(Clause, i, -1, Subst2, Subst1,
+			    i>clause_LastAntecedentLitIndex(Clause), Flags, Precedence))
+    return FALSE;
+  if (!clause_GetFlag(PartnerClause, CLAUSESELECT) &&
+      !inf_LitMaxWith2Subst(PartnerClause, j, -1, Subst2, Subst1,
+		 j>clause_LastAntecedentLitIndex(PartnerClause), Flags, Precedence))
+    return FALSE;
+
+  return TRUE;
+}
+
+
+/**************************************************************/
+/* Inference rules                                            */
+/**************************************************************/
+
+LIST inf_EqualityResolution(CLAUSE GivenClause, BOOL Ordered, FLAGSTORE Flags,
+			    PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause and a flag determining whether ordering
+           constraints apply.
+	   For <Ordered>=TRUE the function makes Equality Resolution
+	   inferences, for <Ordered>=FALSE Reflexivity Resolution
+	   inferences are made.
+	   A flag store.
+	   A precedence.
+  RETURNS: A list of clauses inferred from the GivenClause by
+           Equality/Reflexivity Resolution.
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{
+  LIST    Result;
+  LITERAL ActLit;
+  int     i, last;
+
+#ifdef CHECK
+  if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_EqualityResolution: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (clause_HasEmptyAntecedent(GivenClause) ||
+      !clause_HasSolvedConstraint(GivenClause)) {
+    return list_Nil();
+  }
+
+  Result          = list_Nil();
+  last            = clause_LastAntecedentLitIndex(GivenClause);
+  
+  for (i = clause_FirstAntecedentLitIndex(GivenClause); i <= last; i++) {
+    ActLit = clause_GetLiteral(GivenClause, i);
+    
+    if (clause_LiteralIsEquality(ActLit) &&
+	(clause_LiteralGetFlag(ActLit,LITSELECT) ||
+	 (!clause_GetFlag(GivenClause,CLAUSESELECT) &&
+	  (!Ordered || clause_LiteralIsMaximal(ActLit))))) {
+      TERM Atom;
+      
+      Atom = clause_GetLiteralAtom(GivenClause, i);
+      
+      cont_Check();
+      if (unify_UnifyCom(cont_LeftContext(),
+			 term_FirstArgument(Atom), 
+			 term_SecondArgument(Atom))) {
+	SUBST  mgu;
+	CLAUSE NewClause;
+	int    j, k, bound;
+	
+	subst_ExtractUnifierCom(cont_LeftContext(), &mgu);
+	/* Check postcondition */
+	if (clause_LiteralGetFlag(ActLit,LITSELECT) ||
+	    !Ordered || inf_LitMax(GivenClause, i, -1, mgu, 
+				   FALSE, Flags, Precedence)) {
+	  
+	  NewClause = clause_CreateBody(clause_Length(GivenClause) - 1);
+	  clause_SetNumOfConsLits(NewClause, clause_NumOfConsLits(GivenClause));
+	  clause_SetNumOfAnteLits(NewClause,
+				  (clause_NumOfAnteLits(GivenClause) - 1));
+	  clause_SetNumOfSuccLits(NewClause, clause_NumOfSuccLits(GivenClause));
+	  
+	  bound = clause_LastLitIndex(GivenClause);
+	  /* j iterates over the given clause, k iterates over the new one */
+	  for (j = k = clause_FirstLitIndex(); j <= bound; j++) {
+	    if (j != i) {
+	      clause_SetLiteral(NewClause, k, 
+	        clause_LiteralCreate(subst_Apply(mgu,
+	          term_Copy(clause_GetLiteralTerm(GivenClause,j))),NewClause));
+	      k++;
+	    }
+	  }
+	  clause_SetDataFromFather(NewClause, GivenClause, i, Flags, Precedence);
+	  clause_SetFromEqualityResolution(NewClause);
+	  
+	  Result = list_Cons(NewClause, Result);
+	}
+	subst_Delete(mgu);
+      }
+      cont_Reset();
+    }	/* end of if 'ActLit is maximal'. */
+  } /*end of for 'all literals'. */
+  return(Result);
+}
+
+static CLAUSE inf_ApplyEqualityFactoring(CLAUSE Clause, TERM Left, TERM Right,
+					 int i, int j, SUBST Subst,
+					 FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, two terms, two indices in the clause,
+           a substitution, a flag store and a precedence.
+  RETURNS: A new clause, where <Left>=<Right> is added as antecedent atom,
+           the <i>th literal is deleted, the <j>th kept and
+	   <Subst> is applied to a copy of <clause>.
+***************************************************************/
+{
+  CLAUSE NewClause;
+  TERM   Atom;
+  int    k,c,a,s;
+
+  NewClause = clause_CreateBody(clause_Length(Clause));
+
+  c = clause_LastConstraintLitIndex(Clause);
+  clause_SetNumOfConsLits(NewClause, clause_NumOfConsLits(Clause));
+  a = clause_LastAntecedentLitIndex(Clause);
+  clause_SetNumOfAnteLits(NewClause, clause_NumOfAnteLits(Clause) + 1);
+  s = clause_LastSuccedentLitIndex(Clause);
+  clause_SetNumOfSuccLits(NewClause, clause_NumOfSuccLits(Clause) - 1);
+
+  for (k = clause_FirstLitIndex(); k <= c; k++) {
+    clause_SetLiteral(NewClause, k, 
+      clause_LiteralCreate(subst_Apply(Subst,
+	term_Copy(clause_GetLiteralTerm(Clause, k))),NewClause));
+  }
+
+  for ( ; k <= a; k++) {
+    clause_SetLiteral(NewClause, k, 
+      clause_LiteralCreate(subst_Apply(Subst,
+        term_Copy(clause_GetLiteralTerm(Clause, k))),NewClause));
+  }
+
+  Atom = term_Create(fol_Equality(),
+		     list_Cons(term_Copy(Left),list_List(term_Copy(Right))));
+
+  clause_SetLiteral(NewClause, k, clause_LiteralCreate(
+    term_Create(fol_Not(), list_List(subst_Apply(Subst,Atom))), NewClause));
+
+  a = 1; /* Shift */
+
+  for ( ; k <= s; k++) {
+    if (k == i)
+      a = 0;
+    else {
+      clause_SetLiteral(NewClause, (k + a),
+	clause_LiteralCreate(subst_Apply(Subst,
+	  term_Copy(clause_GetLiteralTerm(Clause, k))),NewClause));
+    }
+  }
+
+  clause_AddParentClause(NewClause, clause_Number(Clause));
+  clause_AddParentLiteral(NewClause, j);
+  clause_SetDataFromFather(NewClause, Clause, i, Flags, Precedence);
+
+  clause_SetFromEqualityFactoring(NewClause);
+
+  return NewClause;
+}
+
+
+static BOOL inf_EqualityFactoringApplicable(CLAUSE Clause, int i, TERM Left,
+					    TERM Right, SUBST Subst,
+					    FLAGSTORE Flags,
+					    PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause <Clause>, the index <i> of a maximal 
+           equality literal in <Clause> <j>, <Left> and 
+	   <Right> are the left and right side of the literal, 
+	   where <Right> is not greater than <Left> wrt the 
+	   ordering, a unifier <Subst>, a flag store and a 
+	   precedence.
+  RETURNS: TRUE iff the literal at index <i> is strictly 
+           maximal in the instantiated clause and <Right> is 
+	   not greater than or equal to <Left> after 
+	   application of the substitution.
+	   Otherwise, the function returns FALSE.
+***************************************************************/
+{
+  ord_RESULT Help;
+
+  /* Literal oriented? */
+  if (!clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause, i))) {
+    TERM NLeft, NRight;
+    NLeft  = subst_Apply(Subst, term_Copy(Left));
+    NRight = subst_Apply(Subst, term_Copy(Right));
+    if ((Help = ord_Compare(NLeft,NRight,Flags, Precedence)) == ord_SmallerThan() ||
+	Help == ord_Equal()) {
+      term_Delete(NLeft);
+      term_Delete(NRight);
+      return FALSE;
+    }
+    term_Delete(NLeft);
+    term_Delete(NRight);
+  }
+  /* Literal maximal? */
+  return inf_LitMax(Clause, i, -1, Subst, FALSE, Flags, Precedence);
+}
+
+
+LIST inf_EqualityFactoring(CLAUSE GivenClause, FLAGSTORE Flags,
+			   PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, a flag store and a precedence.
+  RETURNS: A list of clauses derivable from 'GivenClause' by EF.
+***************************************************************/
+{
+  LIST    Result;
+  LITERAL ActLit;
+  int     i, j, last;
+  SUBST   mgu;
+
+#ifdef CHECK
+  if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_EqualityFactoring: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (clause_HasEmptySuccedent(GivenClause) ||
+      clause_GetFlag(GivenClause, CLAUSESELECT) ||
+      !clause_HasSolvedConstraint(GivenClause)) {
+    return list_Nil();
+  }
+
+  Result = list_Nil();
+  
+  last = clause_LastSuccedentLitIndex(GivenClause);
+  
+  for (i = clause_FirstSuccedentLitIndex(GivenClause); i <= last; i++) {
+    
+    ActLit = clause_GetLiteral(GivenClause, i);
+    
+    if (clause_LiteralIsMaximal(ActLit) &&
+	clause_LiteralIsEquality(ActLit)) {
+      TERM    Atom, Left, Right;
+      LITERAL PartnerLit;
+      
+      Atom  = clause_LiteralAtom(ActLit);
+      Left  = term_FirstArgument(Atom);
+      Right = term_SecondArgument(Atom);
+      
+      for (j = clause_FirstSuccedentLitIndex(GivenClause); j <= last; j++) {
+	PartnerLit = clause_GetLiteral(GivenClause, j);
+	if (i != j && clause_LiteralIsEquality(PartnerLit)) {
+	  /* i==j can be excluded since this inference would either generate */
+	  /* a copy of the given clause (if one side of the equality is      */
+	  /* unified with itself), or generate a tautology (if different     */
+	  /* sides of the equality are unified).                             */
+	  TERM PartnerAtom, PartnerLeft, PartnerRight;
+	  
+	  PartnerAtom  = clause_LiteralAtom(PartnerLit);
+	  PartnerLeft  = term_FirstArgument(PartnerAtom);
+	  PartnerRight = term_SecondArgument(PartnerAtom);
+
+	  /* try <Left> and <PartnerLeft> */
+	  cont_Check();
+	  if (unify_UnifyCom(cont_LeftContext(), Left, PartnerLeft)) {
+	    subst_ExtractUnifierCom(cont_LeftContext(), &mgu);
+	    if (inf_EqualityFactoringApplicable(GivenClause, i, Left, Right,
+						mgu, Flags, Precedence))
+	      Result = list_Cons(inf_ApplyEqualityFactoring(GivenClause,Right,
+							    PartnerRight,i,j,
+							    mgu,Flags, 
+							    Precedence),
+				 Result);
+	    subst_Delete(mgu);
+	  }
+	  cont_Reset();
+
+	  /* try <Left> and <PartnerRight> */
+	  cont_Check();
+	  if (unify_UnifyCom(cont_LeftContext(), Left, PartnerRight)) {
+	    subst_ExtractUnifierCom(cont_LeftContext(), &mgu);
+	    
+	    if (inf_EqualityFactoringApplicable(GivenClause, i, Left, Right,
+						mgu, Flags, Precedence))
+	      Result = list_Cons(inf_ApplyEqualityFactoring(GivenClause,Right,
+							    PartnerLeft,i,j,
+							    mgu,Flags, 
+							    Precedence),
+				 Result);
+	    subst_Delete(mgu);
+	  }
+	  cont_Reset();
+
+	  if (!clause_LiteralIsOrientedEquality(ActLit)) {
+	    /* try <Right> and <PartnerLeft> */
+	    cont_Check();
+	    if (unify_UnifyCom(cont_LeftContext(), Right, PartnerLeft)) {
+	      subst_ExtractUnifierCom(cont_LeftContext(), &mgu);
+	      
+	      if (inf_EqualityFactoringApplicable(GivenClause, i, Right, Left,
+						  mgu, Flags, Precedence))
+		Result = list_Cons(inf_ApplyEqualityFactoring(GivenClause,Left,
+							      PartnerRight,i,j,
+							      mgu,Flags,
+							      Precedence),
+				   Result);
+	      subst_Delete(mgu);
+	    }
+	    cont_Reset();
+	    
+	    /* try <Right> and <PartnerRight> */
+	    cont_Check();
+	    if (unify_UnifyCom(cont_LeftContext(), Right, PartnerRight)) {
+	      subst_ExtractUnifierCom(cont_LeftContext(), &mgu);
+	      
+	      if (inf_EqualityFactoringApplicable(GivenClause, i, Right, Left,
+						  mgu, Flags, Precedence))
+		Result = list_Cons(inf_ApplyEqualityFactoring(GivenClause,Left,
+							      PartnerLeft,i,j,
+							      mgu,Flags,
+							      Precedence),
+				   Result);
+	      subst_Delete(mgu);
+	    }
+	    cont_Reset();
+	  }
+	}
+      }
+    }
+  }
+  return Result;
+}
+
+
+/* START of block with new term replacement */
+
+static BOOL inf_NAllTermsRplac(TERM Term, TERM TestTerm, TERM RplacTerm,
+			       SUBST Subst)
+/**************************************************************
+  INPUT:   Three terms, a substitution and an integer.
+           All occurrences of <TestTerm> in <Term> are replaced
+           by <RplacTerm>. The substitution <Subst> is applied to <Term>.
+  RETURNS: TRUE, if TestTerm was replaced by RplacTerm,
+           FALSE otherwise.
+  EFFECT:  <Term> is destructively changed!
+***************************************************************/
+{
+  LIST ArgListNode;
+  BOOL Replaced;
+  int  Bottom;
+
+  Replaced = FALSE;
+
+  /* check if whole term must be replaced */
+  if (term_Equal(Term, TestTerm)) {
+    term_RplacTop(Term,term_TopSymbol(RplacTerm));
+    ArgListNode = term_ArgumentList(Term);
+    term_RplacArgumentList(Term, term_CopyTermList(term_ArgumentList(RplacTerm)));
+    term_DeleteTermList(ArgListNode);
+    return TRUE;
+  }
+
+  if (term_IsVariable(Term))
+    subst_Apply(Subst, Term);
+
+  /* if not, scan whole term.  */
+  if (!list_Empty(term_ArgumentList(Term))) {
+
+    Bottom = stack_Bottom();
+    stack_Push(term_ArgumentList(Term));
+
+    while (!stack_Empty(Bottom)) {
+      ArgListNode = stack_Top();
+      Term        = (TERM)list_Car(ArgListNode);
+      stack_RplacTop(list_Cdr(ArgListNode));
+
+      if (term_Equal(Term, TestTerm)) {
+	Replaced = TRUE;
+	list_Rplaca(ArgListNode, term_Copy(RplacTerm));
+	term_Delete(Term);
+      }      
+      else {
+	if (term_IsComplex(Term))
+	  stack_Push(term_ArgumentList(Term));
+	else if (term_IsVariable(Term))
+	  subst_Apply(Subst,Term);
+      }
+
+      /* remove empty lists (corresponding to scanned terms) */
+      while (!stack_Empty(Bottom) && list_Empty(stack_Top()))
+	stack_Pop();
+    }
+  }
+  return Replaced;
+}
+
+
+static TERM inf_AllTermsRplac(TERM Term, TERM TestTerm, TERM RplacTerm,
+			      SUBST Subst)
+/**************************************************************
+  INPUT:   Three terms, a substitution.
+           All occurrences of <TestTerm> in A COPY of <Term> are replaced
+           by <RplacTerm>. The substitution <Subst> is applied to 
+	   the copy of <Term>. If no occurrence is found,
+	   NULL is returned.
+	   This function is not destructive
+	   like NAllTermRplac.
+  RETURNS: TRUE, if TestTerm was replaced by RplacTerm,
+           FALSE otherwise.
+***************************************************************/
+{ 
+  TERM ActTerm = term_Copy(Term);
+  
+  if (!inf_NAllTermsRplac(ActTerm,TestTerm, RplacTerm, Subst )) {
+    term_Delete(ActTerm);
+    ActTerm = NULL;
+  }
+ 
+  return(ActTerm);
+}
+
+static TERM inf_AllTermsSideRplacs(TERM Term, TERM TestTerm, TERM RplacTerm,
+				   SUBST Subst, BOOL Right)
+/**************************************************************
+  INPUT:   Three terms, a substitution and a boolean flag. 
+           <Term> is typically an equality term.
+  RETURNS: If <TestTerm> occurs in the right (Right=TRUE) or
+           left side (Right=FALSE) of <Term>:
+
+           A copy of the term where all occurrences of <TestTerm>
+	   in the ENTIRE <Term> are replaced by <RplacTerm> and
+	   the substitution <Subst> is applied to all other subterms.
+
+	   If <TestTerm> does not occur in the right/left side of
+	   <Term>, NULL is returned.
+
+	   In non-equality terms, The 'sides' correspond to the 
+	   first and second argument of the term.
+***************************************************************/
+{
+  TERM   ActTerm = term_Copy(Term); 
+  TERM   ReplSide, OtherSide; /* ReplSide is the side in which terms are
+				 replaced */
+
+  if (Right) { 
+    ReplSide  = term_SecondArgument(ActTerm);
+    OtherSide = term_FirstArgument(ActTerm);
+  }
+  else { 
+    ReplSide  = term_FirstArgument(ActTerm);
+    OtherSide = term_SecondArgument(ActTerm);
+  }
+
+  if (inf_NAllTermsRplac(ReplSide, TestTerm, RplacTerm, Subst))
+    /* If <TestTerm> occurs in <ReplSide> also replace it in <OtherSide>. */
+    inf_NAllTermsRplac(OtherSide, TestTerm, RplacTerm, Subst);
+  else { 
+     term_Delete(ActTerm);
+     ActTerm = NULL;
+  }
+
+  return ActTerm;
+}
+
+
+static TERM inf_AllTermsRightRplac(TERM Term, TERM TestTerm, TERM RplacTerm,
+				   SUBST Subst)
+/**************************************************************
+  INPUT:   Three terms, a substitution.
+           <Term> is typically an equality term.
+  RETURNS: See inf_AllTermSideRplac with argument
+           'Right' set to TRUE
+**************************************************************/
+{
+  return(inf_AllTermsSideRplacs(Term, TestTerm, RplacTerm, Subst, TRUE));
+}
+
+
+static TERM inf_AllTermsLeftRplac(TERM Term, TERM TestTerm, TERM RplacTerm,
+				  SUBST Subst)
+/**************************************************************
+  INPUT:   Three terms, a substitution.
+           <Term> is typically an equality term.
+  RETURNS: See inf_AllTermSideRplac with argument
+           'Right' set to FALSE.
+***************************************************************/
+{
+  return(inf_AllTermsSideRplacs(Term, TestTerm, RplacTerm, Subst, FALSE));
+}
+
+
+/*  END of block with new term replacement */
+
+
+static CLAUSE inf_ApplyGenSuperposition(CLAUSE Clause, int ci, SUBST Subst,
+					CLAUSE PartnerClause, int pci,
+					SUBST PartnerSubst, TERM SupAtom,
+					BOOL Right, BOOL OrdPara, BOOL MaxPara,
+					FLAGSTORE Flags, PRECEDENCE Precedence)
+/************************************************************** 
+  INPUT:  Two clauses where a generalized superposition inference can be
+          applied using the positive equality literal <i> from <Clause> with
+          subst <Subst> using the literal <j> from <PartnerClause> with subst
+          <PartnerSubst> where SupAtom is a derivable atom. Returns
+	  NULL if SupAtom is NULL.
+
+	   Right is TRUE if the inference is a superposition right inference
+	   Right is FALSE if the inference is a superposition left inference,
+
+	   where the inference is selected by MaxPara and OrdPara:
+	   (see also inf_GenSuperpositionLeft)
+	   
+	   OrdPara=TRUE, MaxPara=TRUE 
+	   -> Superposition (Left or Right)
+
+	   OrdPara=TRUE, MaxPara=FALSE
+	   -> ordered Paramodulation
+
+	   OrdPara=FALSE, MaxPara=FALSE
+	   -> simple Paramodulation
+
+	   OrdPara=FALSE, MaxPara=TRUE
+	   -> not defined
+
+	   A flag store.
+	   A precedence.
+  RETURNS: The new clause.
+  MEMORY:  Memory for the new clause is allocated.
+***************************************************************/
+{
+  CLAUSE NewClause;
+  int    j,lc,la,ls,pls,pla,plc,help;
+
+#ifdef CHECK
+  if (!OrdPara && MaxPara) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_ApplyGenSuperposition : Illegal inference");
+    misc_ErrorReport("\n rule selection, OrdPara=FALSE and MaxPara=TRUE.");
+    misc_FinishErrorReport();
+  }
+  if (SupAtom == NULL) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_ApplyGenSuperposition: Atom is NULL.");
+    misc_FinishErrorReport();
+    return clause_Null();
+  }
+#endif
+
+  pls = clause_LastSuccedentLitIndex(PartnerClause);
+  pla = clause_LastAntecedentLitIndex(PartnerClause);
+  plc = clause_LastConstraintLitIndex(PartnerClause);
+
+  ls  = clause_LastSuccedentLitIndex(Clause);
+  la  = clause_LastAntecedentLitIndex(Clause);
+  lc  = clause_LastConstraintLitIndex(Clause);
+
+
+  NewClause = clause_CreateBody(clause_Length(Clause) - 1 +
+				clause_Length(PartnerClause));
+
+  clause_SetNumOfConsLits(NewClause, (clause_NumOfConsLits(Clause) +
+				      clause_NumOfConsLits(PartnerClause)));
+  clause_SetNumOfAnteLits(NewClause, (clause_NumOfAnteLits(Clause) +
+				      clause_NumOfAnteLits(PartnerClause)));
+  clause_SetNumOfSuccLits(NewClause, ((clause_NumOfSuccLits(Clause) -1)+
+				      clause_NumOfSuccLits(PartnerClause)));
+
+  /* First set the literals from the Clause : */
+    
+  for (j = clause_FirstLitIndex(); j <= lc; j++) {
+    clause_SetLiteral(NewClause, j, 
+      clause_LiteralCreate(subst_Apply(Subst, term_Copy(
+       	clause_GetLiteralTerm(Clause, j))),NewClause));
+  }
+
+  /* help = number of literals to leave empty */
+  help = clause_NumOfConsLits(PartnerClause);
+
+  for ( ; j <= la; j++) {
+    clause_SetLiteral(NewClause, (j + help), 
+      clause_LiteralCreate(subst_Apply(Subst, term_Copy(
+    	clause_GetLiteralTerm(Clause, j))),NewClause));
+  }
+
+  /* help = number of literals to leave empty */
+  help += clause_NumOfAnteLits(PartnerClause);
+
+  for ( ; j <= ls; j++) {
+    if (j != ci) {
+      /* The literal used in the inference isn't copied */
+      clause_SetLiteral(NewClause, (j + help), 
+       	clause_LiteralCreate(subst_Apply(Subst,
+	  term_Copy(clause_GetLiteralTerm(Clause, j))),NewClause));
+
+    } else {
+      /*the index has to be decreased to avoid an empty literal! */
+      help--;
+    }
+  }
+
+  /* Now we consider the PartnerClause : */
+
+  /* help = number of already set constraint (Clause) literals */
+  help = clause_NumOfConsLits(Clause);
+
+  for (j = clause_FirstLitIndex(); j <= plc; j++) {
+    clause_SetLiteral(NewClause, (j + help), 
+      clause_LiteralCreate(subst_Apply(PartnerSubst,
+        term_Copy(clause_GetLiteralTerm(PartnerClause, j))),NewClause));
+  }
+
+  /* help = number of already set constraint and antecedent Given-literals */
+  help += clause_NumOfAnteLits(Clause);
+
+  for ( ; j <= pla; j++) {
+    if (j != pci) {
+      clause_SetLiteral(NewClause, (j + help), 
+	clause_LiteralCreate(subst_Apply(PartnerSubst,
+	  term_Copy(clause_GetLiteralTerm(PartnerClause, j))),NewClause));
+    } else {
+      /* The PartnerLit is modified appropriately!   */
+      clause_SetLiteral(NewClause, (j + help), clause_LiteralCreate(
+	term_Create(fol_Not(),list_List(SupAtom)), NewClause));
+    }
+  }
+
+
+  /* help = number of already set Given-literals */
+  help = clause_Length(Clause) - 1;
+
+  for ( ; j <= pls; j++) {
+    if (j != pci) {
+      /* The PartnerLit isn't copied! */
+      clause_SetLiteral(NewClause, (j + help), 
+	clause_LiteralCreate(subst_Apply(PartnerSubst,
+	  term_Copy(clause_GetLiteralTerm(PartnerClause, j))),NewClause));
+
+    } else {
+      /* The PartnerLit is modified appropriately!   */
+      clause_SetLiteral(NewClause, (j + help),
+			clause_LiteralCreate(SupAtom, NewClause));
+    }
+  }
+    
+  /* 
+   *  Set inference type. Note that, in the case of (ordered) paramodulation,
+   *  we do not distinguish which side was paramodulated into, as compared
+   *  to the case of superposition. 
+   */
+
+  if (OrdPara && MaxPara) {
+    if (Right)
+      clause_SetFromSuperpositionRight(NewClause);
+    else
+      clause_SetFromSuperpositionLeft(NewClause);
+  } 
+  else if (OrdPara && !MaxPara)
+    clause_SetFromOrderedParamodulation(NewClause);
+  else 
+    clause_SetFromParamodulation(NewClause);
+
+  clause_SetDataFromParents(NewClause, PartnerClause, pci, Clause, ci, Flags,
+			    Precedence);
+
+  return NewClause;
+}
+
+
+/* START of block with new superposition right rule */
+
+static LIST inf_GenLitSPRight(CLAUSE Clause, TERM Left, TERM Right, int i,
+			      SHARED_INDEX ShIndex, BOOL OrdPara, BOOL MaxPara,
+			      FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause (unshared) with a positive equality literal
+           at position <i> where <Left> and <Right> are the arguments
+	   of just that literal and <Right> is not greater wrt. the
+	   ordering than <Left>,
+	   two boolean flags for controlling inference
+           preconditions (see inf_GenSuperpositionRight),
+	   a flag store and a precedence.
+  RETURNS: A list of clauses derivable with the literals owning
+           clause by general superposition right wrt. the Index.
+	   (see inf_GenSuperpositionRight for selection of inference
+	   rule by OrdPara/MaxPara)
+  MEMORY:  The list of clauses is extended, where memory for the
+           list and the clauses is allocated.
+***************************************************************/
+{
+  LIST Result, Terms;
+
+  Result  = list_Nil();
+  Terms   = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex),
+			  cont_RightContext(), Left);
+
+  for ( ; !list_Empty(Terms); Terms = list_Pop(Terms)) {
+    LIST Lits;
+    TERM Term;
+
+    Term = (TERM)list_First(Terms);
+
+    if (!term_IsVariable(Term) && !symbol_IsPredicate(term_TopSymbol(Term))) {
+
+      Lits = sharing_GetDataList(Term, ShIndex);
+
+      for ( ; !list_Empty(Lits); Lits = list_Pop(Lits)) {
+	LITERAL PartnerLit;
+	TERM    PartnerAtom;
+	CLAUSE  PartnerClause;
+	int     pli;
+
+	PartnerLit    = (LITERAL)list_Car(Lits);
+	PartnerAtom   = clause_LiteralAtom(PartnerLit);
+	pli           = clause_LiteralGetIndex(PartnerLit);
+	PartnerClause = clause_LiteralOwningClause(PartnerLit);
+
+	if (!clause_GetFlag(PartnerClause,CLAUSESELECT) &&
+	    (!MaxPara || clause_LiteralGetFlag(PartnerLit,STRICTMAXIMAL)) &&
+	    !clause_GetFlag(PartnerClause,NOPARAINTO) &&
+	    clause_LiteralIsPositive(PartnerLit) &&
+	    clause_HasSolvedConstraint(PartnerClause)) {
+
+	  SUBST  Subst, PartnerSubst;
+	  TERM   NewLeft,NewRight;
+	  SYMBOL PartnerMaxVar;
+	  TERM   SupAtom;
+
+	  SupAtom = (TERM)NULL;
+
+	  PartnerMaxVar = clause_MaxVar(PartnerClause);
+	  NewLeft       = Left;
+	  clause_RenameVarsBiggerThan(Clause, PartnerMaxVar);
+	  cont_Check();
+	  unify_UnifyNoOC(cont_LeftContext(), Left, cont_RightContext(), Term);
+	  subst_ExtractUnifier(cont_LeftContext(), &Subst, cont_RightContext(), &PartnerSubst);
+	  cont_Reset();
+	  if (!MaxPara ||
+	      inf_LiteralsMax(Clause, i, Subst, PartnerClause, pli,
+			      PartnerSubst, Flags, Precedence)) {
+	    NewRight = subst_Apply(Subst, term_Copy(Right));
+	    if (OrdPara &&
+		!clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i)))
+	      NewLeft  = subst_Apply(Subst, term_Copy(Left));
+	    if (!OrdPara ||
+		NewLeft == Left ||       /* TRUE, if oriented */
+		ord_Compare(NewLeft,NewRight, Flags, Precedence) != ord_SmallerThan()) {
+	      if (!MaxPara || clause_LiteralIsPredicate(PartnerLit)) {
+		SupAtom = inf_AllTermsRplac(PartnerAtom, Term,
+					    NewRight, PartnerSubst);
+	      } else {
+		/* Superposition and <PartnerLit> is equality */
+		if (clause_LiteralIsOrientedEquality(PartnerLit))
+		  SupAtom = inf_AllTermsLeftRplac(PartnerAtom, Term,
+						  NewRight, PartnerSubst);
+		else {
+		  TERM NewPartnerLeft,NewPartnerRight;
+		  NewPartnerLeft  =
+		    subst_Apply(PartnerSubst, 
+				term_Copy(term_FirstArgument(PartnerAtom)));
+		  NewPartnerRight =
+		    subst_Apply(PartnerSubst, 
+				term_Copy(term_SecondArgument(PartnerAtom)));
+		  switch (ord_Compare(NewPartnerLeft,NewPartnerRight,
+				      Flags, Precedence)) {
+		  case ord_SMALLER_THAN:
+		    SupAtom = inf_AllTermsRightRplac(PartnerAtom,Term,
+						      NewRight,PartnerSubst);
+		    break;
+		  case ord_GREATER_THAN:
+		    SupAtom = inf_AllTermsLeftRplac(PartnerAtom,Term,
+						     NewRight,PartnerSubst);
+		    break;
+		  default:
+		    SupAtom = inf_AllTermsRplac(PartnerAtom,Term,
+						 NewRight,PartnerSubst);
+		  }
+		  term_Delete(NewPartnerLeft);
+		  term_Delete(NewPartnerRight);
+		}
+	      }
+
+	      if (SupAtom != NULL)
+		Result =
+		  list_Cons(inf_ApplyGenSuperposition(Clause, i, Subst,
+						      PartnerClause, pli,
+						      PartnerSubst, SupAtom,
+						      TRUE, OrdPara, MaxPara,
+						      Flags, Precedence), 
+			    Result);
+	    }
+	    if (NewLeft != Left)
+	      term_Delete(NewLeft);
+	    term_Delete(NewRight);
+	  }
+	  subst_Delete(Subst);
+	  subst_Delete(PartnerSubst);
+	}
+      }
+    }
+  }
+  return Result;
+}
+
+
+static LIST inf_GenSPRightEqToGiven(CLAUSE Clause, int i, BOOL Left,
+				    SHARED_INDEX ShIndex, BOOL OrdPara,
+				    BOOL MaxPara, BOOL Unit, FLAGSTORE Flags,
+				    PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   An unshared clause, the index of a succedent literal
+           that is an equality literal and a boolean value which
+	   argument to use:
+	   If Left==TRUE then the left argument is used
+	   otherwise the right argument.
+	   Three boolean flags for controlling inference
+           preconditions (see inf_GenSuperpositionRight).
+	   A flag store.
+	   A precedence.
+  RETURNS: A list of clauses derivable from general superposition right on the
+           GivenCopy  wrt. the Index.
+           (see inf_GenSuperpositionRight for selection of inference
+	   rule by OrdPara/MaxPara)
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{
+  LIST    Result, TermList, Parents;
+  int     Bottom;
+  LITERAL Lit;
+  TERM    Atom, Term, PartnerTerm, PartnerEq;
+
+  Result = list_Nil();
+  Lit    = clause_GetLiteral(Clause,i);
+  Atom   = clause_LiteralAtom(Lit);
+
+#ifdef CHECK
+  if (!fol_IsEquality(Atom) ||
+      (MaxPara && clause_LiteralIsOrientedEquality(Lit) && !Left) ||
+      (MaxPara && !clause_LiteralGetFlag(Lit, STRICTMAXIMAL))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_GenSPRightEqToGiven: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Bottom = stack_Bottom();
+  if (Left) /* Top Level considered in inf_LitSPRight */ 
+    sharing_PushListOnStack(term_ArgumentList(term_FirstArgument(Atom)));
+  else
+    sharing_PushListOnStack(term_ArgumentList(term_SecondArgument(Atom)));
+
+  while (!stack_Empty(Bottom)) {
+    Term = (TERM)stack_PopResult();
+    if (!term_IsVariable(Term)) {
+      /* Superposition into variables is not necessary */
+      TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex),
+			       cont_RightContext(), Term);
+      for ( ; !list_Empty(TermList); TermList = list_Pop(TermList)) {
+	PartnerTerm = (TERM)list_Car(TermList);
+	for (Parents = term_SupertermList(PartnerTerm);
+	     !list_Empty(Parents); Parents = list_Cdr(Parents)) {
+	  PartnerEq = (TERM)list_Car(Parents);
+	  if (fol_IsEquality(PartnerEq)) {
+	    CLAUSE  PartnerClause;
+	    LITERAL PartnerLit;
+	    LIST    Scl;
+	    int     j;
+	    for (Scl = sharing_NAtomDataList(PartnerEq);
+		 !list_Empty(Scl); Scl = list_Cdr(Scl)) {
+	      PartnerLit    = (LITERAL)list_Car(Scl);
+	      j             = clause_LiteralGetIndex(PartnerLit);
+	      PartnerClause = clause_LiteralOwningClause(PartnerLit);
+	      if (!clause_GetFlag(PartnerClause,CLAUSESELECT) &&
+		  (!MaxPara ||
+		   clause_LiteralGetFlag(PartnerLit,STRICTMAXIMAL)) &&
+		  (!OrdPara || PartnerTerm==term_FirstArgument(PartnerEq) ||
+		   !clause_LiteralIsOrientedEquality(PartnerLit)) &&
+		  clause_LiteralIsPositive(PartnerLit) &&
+		  clause_Number(PartnerClause) != clause_Number(Clause) &&
+		  (!Unit || clause_Length(PartnerClause) == 1) &&
+		  clause_HasSolvedConstraint(PartnerClause)) {
+		/* We exclude the same clause since that inference will be */
+		/* made by the "forward" function inf_GenLitSPRight.       */
+		SYMBOL MaxVar;
+		SUBST  Subst, PartnerSubst;
+
+		MaxVar = clause_MaxVar(PartnerClause);
+		clause_RenameVarsBiggerThan(Clause, MaxVar);
+		cont_Check();
+		unify_UnifyNoOC(cont_LeftContext(), Term, cont_RightContext(),
+				PartnerTerm);
+		subst_ExtractUnifier(cont_LeftContext(), &Subst,
+				     cont_RightContext(), &PartnerSubst);
+		cont_Reset();
+		if (!MaxPara ||
+		    inf_LiteralsMax(Clause, i, Subst, PartnerClause, j,
+				    PartnerSubst, Flags, Precedence)) {
+		  TERM PartnerLeft,PartnerRight;
+		  BOOL Check, PartnerCheck;
+		  PartnerLeft = PartnerRight = NULL;
+		  PartnerCheck = Check = TRUE;
+		  if (OrdPara &&
+		      !clause_LiteralIsOrientedEquality(PartnerLit)) {
+		    /* Check post condition for partner literal */
+		    if (PartnerTerm == term_FirstArgument(PartnerEq))
+		      PartnerRight = term_SecondArgument(PartnerEq);
+		    else
+		      PartnerRight = term_FirstArgument(PartnerEq);
+		    PartnerLeft  = subst_Apply(PartnerSubst,
+					       term_Copy(PartnerTerm));
+		    PartnerRight = subst_Apply(PartnerSubst,
+					       term_Copy(PartnerRight));
+		    PartnerCheck = (ord_Compare(PartnerLeft, PartnerRight,
+						Flags, Precedence)
+				    != ord_SmallerThan());
+		  }
+		  if (PartnerCheck &&
+		      MaxPara && !clause_LiteralIsOrientedEquality(Lit)) {
+		    /* Check post condition for literal in given clause */
+		    TERM NewLeft, NewRight;
+		    if (Left) {
+		      NewLeft  = term_FirstArgument(Atom);
+		      NewRight = term_SecondArgument(Atom);
+		    } else {
+		      NewLeft  = term_SecondArgument(Atom);
+		      NewRight = term_FirstArgument(Atom);
+		    }
+		    NewLeft  = subst_Apply(Subst, term_Copy(NewLeft));
+		    NewRight = subst_Apply(Subst, term_Copy(NewRight));
+		    Check = (ord_Compare(NewLeft, NewRight, Flags, Precedence)
+			     != ord_SmallerThan());
+		    term_Delete(NewLeft);
+		    term_Delete(NewRight);
+		  }
+		  if (Check && PartnerCheck) {
+		    /* Make inference only if both tests were successful */
+		    TERM SupAtom;
+		    SupAtom = NULL;
+		    if (PartnerRight == NULL) {
+		      if (PartnerTerm==term_FirstArgument(PartnerEq))
+			PartnerRight = term_SecondArgument(PartnerEq);
+		      else
+			PartnerRight = term_FirstArgument(PartnerEq);
+		      PartnerRight = subst_Apply(PartnerSubst,
+						 term_Copy(PartnerRight));
+		    }
+		    if (Left)
+		      SupAtom = inf_AllTermsLeftRplac(Atom, Term,
+						      PartnerRight, Subst);
+		    else 
+		      SupAtom = inf_AllTermsRightRplac(Atom, Term,
+						       PartnerRight, Subst);
+#ifdef CHECK
+		    if (SupAtom == NULL) {
+		      misc_StartErrorReport();
+		      misc_ErrorReport("\n In inf_GenSPRightEqToGiven:");
+		      misc_ErrorReport(" replacement wasn't possible.");
+		      misc_FinishErrorReport();
+		    }
+#endif
+		    Result =
+		      list_Cons(inf_ApplyGenSuperposition(PartnerClause, j,
+							  PartnerSubst, Clause,
+							  i, Subst, SupAtom,
+							  TRUE,OrdPara,MaxPara,
+							  Flags, Precedence), 
+				Result);
+		  }
+		  if (PartnerLeft != term_Null())
+		    term_Delete(PartnerLeft);
+		  if (PartnerRight != term_Null())
+		    term_Delete(PartnerRight);
+		}
+		subst_Delete(Subst);
+		subst_Delete(PartnerSubst);
+	      }
+	    }
+	  }
+	}
+      }
+    }
+  }
+  return Result;
+}
+
+
+static LIST inf_GenSPRightLitToGiven(CLAUSE Clause, int i, TERM Atom,
+				     SHARED_INDEX ShIndex, BOOL OrdPara,
+				     BOOL MaxPara, BOOL Unit, FLAGSTORE Flags,
+				     PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   An unshared clause, the index of a succedent literal
+           that is not an equality literal and its atom,
+	   three boolean flags for controlling inference
+           preconditions (see inf_GenSuperpositionRight),
+	   a flag store and a precedence.
+  RETURNS: A list of clauses derivable from general superposition right on the
+           GivenCopy  wrt. the Index.
+           (see inf_GenSuperpositionRight for selection of inference
+	   rule by OrdPara/MaxPara)
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{
+  LIST    Result, TermList, ParentList;
+  int     Bottom;
+  TERM    Term, PartnerTerm, PartnerEq;
+
+  Result = list_Nil();
+
+  Bottom = stack_Bottom();
+  sharing_PushListOnStack(term_ArgumentList(Atom));
+
+  while (!stack_Empty(Bottom)) {
+    Term = (TERM)stack_PopResult();
+    if (!term_IsVariable(Term)) {
+      /* Superposition into variables is not necessary */
+      TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex),
+			       cont_RightContext(), Term);
+      for ( ; !list_Empty(TermList); TermList=list_Pop(TermList)) {
+	PartnerTerm = (TERM)list_Car(TermList);
+	for (ParentList = term_SupertermList(PartnerTerm);
+	     !list_Empty(ParentList); ParentList = list_Cdr(ParentList)) {
+	  PartnerEq = (TERM)list_Car(ParentList);
+	  if (fol_IsEquality(PartnerEq)) {
+	    CLAUSE  PartnerClause;
+	    LITERAL PartnerLit;
+	    LIST    Scl;
+	    int     j;
+	    for (Scl = sharing_NAtomDataList(PartnerEq);
+		 !list_Empty(Scl); Scl = list_Cdr(Scl)) {
+	      PartnerLit    = (LITERAL)list_Car(Scl);
+	      j             = clause_LiteralGetIndex(PartnerLit);
+	      PartnerClause = clause_LiteralOwningClause(PartnerLit);
+	      if (!clause_GetFlag(PartnerClause,CLAUSESELECT) &&
+		  (!MaxPara ||
+		   clause_LiteralGetFlag(PartnerLit,STRICTMAXIMAL)) &&
+		  (!OrdPara || PartnerTerm==term_FirstArgument(PartnerEq) ||
+		   !clause_LiteralIsOrientedEquality(PartnerLit)) &&
+		  clause_LiteralIsPositive(PartnerLit) &&
+		  clause_Number(PartnerClause) != clause_Number(Clause) && 
+		  (!Unit || clause_Length(PartnerClause) == 1) &&
+		  clause_HasSolvedConstraint(PartnerClause)) {
+		/* We exclude the same clause since that inference will be */
+		/* made by the "forward" function inf_GenLitSPRight.       */
+		SYMBOL MaxVar;
+		TERM   PartnerLeft,PartnerRight;
+		SUBST  Subst, PartnerSubst;
+		TERM   SupAtom;
+
+		SupAtom = (TERM)NULL;
+		MaxVar      = clause_MaxVar(PartnerClause);
+		clause_RenameVarsBiggerThan(Clause,MaxVar);
+		cont_Check();
+		unify_UnifyNoOC(cont_LeftContext(), Term,
+				cont_RightContext(),PartnerTerm);
+		subst_ExtractUnifier(cont_LeftContext(), &Subst,
+				     cont_RightContext(),&PartnerSubst);
+		cont_Reset();
+
+		if (!MaxPara ||
+		    inf_LiteralsMax(Clause, i, Subst, PartnerClause, j,
+				    PartnerSubst, Flags, Precedence)) {
+		  PartnerLeft = subst_Apply(PartnerSubst,
+					    term_Copy(PartnerTerm));
+		  if (PartnerTerm == term_FirstArgument(PartnerEq))
+		    PartnerRight =
+		      subst_Apply(PartnerSubst,
+				  term_Copy(term_SecondArgument(PartnerEq)));
+		  else
+		    PartnerRight =
+		      subst_Apply(PartnerSubst,
+				  term_Copy(term_FirstArgument(PartnerEq)));
+
+		  if (!OrdPara ||
+		      clause_LiteralIsOrientedEquality(PartnerLit) ||
+		      ord_Compare(PartnerLeft,PartnerRight, Flags, Precedence)
+		      != ord_SmallerThan()) {
+		    SupAtom = inf_AllTermsRplac(Atom,Term,PartnerRight,Subst);
+#ifdef CHECK
+		    if (SupAtom == NULL) {
+		      misc_StartErrorReport();
+		      misc_ErrorReport("\n In inf_GenSPRightLitToGiven:");
+		      misc_ErrorReport(" replacement wasn't possible.");
+		      misc_FinishErrorReport();
+		    }
+#endif
+		    Result =
+		      list_Cons(inf_ApplyGenSuperposition(PartnerClause, j,
+							  PartnerSubst, Clause,
+							  i, Subst, SupAtom,
+							  TRUE,OrdPara,MaxPara,
+							  Flags, Precedence),
+				Result);
+		  
+		  }
+		  term_Delete(PartnerLeft);
+		  term_Delete(PartnerRight);
+		}
+		subst_Delete(Subst);
+		subst_Delete(PartnerSubst);
+	      }
+	    }
+	  }
+	}
+      }
+    }
+  }
+  return Result;
+}
+
+
+static LIST inf_GenSPRightToGiven(CLAUSE Clause, int i, SHARED_INDEX ShIndex, 
+				  BOOL OrdPara, BOOL MaxPara, BOOL Unit,
+				  FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   An unshared clause, the index of a succedent literal
+           and an index of shared clauses,
+           three boolean flags for controlling inference
+           preconditions (see inf_GenSuperpositionRight),
+	   a flag store and a precedence.
+  RETURNS: A list of clauses derivable from superposition right on the
+           GivenCopy  wrt. the Index.
+	   (see inf_GenSuperpositionRight for selection of inference
+	   rule by OrdPara/MaxPara)
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{
+  TERM Atom;
+  LIST Result;
+  
+#ifdef CHECK
+  if (clause_GetFlag(Clause, NOPARAINTO) ||
+      clause_GetFlag(Clause, CLAUSESELECT) ||
+      (MaxPara &&
+       !clause_LiteralGetFlag(clause_GetLiteral(Clause,i), STRICTMAXIMAL))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_GenSPRightToGiven: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Result  = list_Nil();
+  Atom    = clause_LiteralAtom(clause_GetLiteral(Clause,i));
+  
+  if (fol_IsEquality(Atom)) {
+    Result = list_Nconc(inf_GenSPRightEqToGiven(Clause,i,TRUE,ShIndex,OrdPara,
+						MaxPara,Unit,Flags, Precedence),
+			Result);
+    
+    if (!MaxPara ||
+	!clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i)))
+      /* For SPm and OPm always try other direction, for SpR try it */
+      /* only if the literal is not oriented.                       */
+      Result = list_Nconc(inf_GenSPRightEqToGiven(Clause, i, FALSE, ShIndex,
+						  OrdPara,MaxPara,Unit,
+						  Flags, Precedence),
+			  Result);
+  } else
+    Result = list_Nconc(inf_GenSPRightLitToGiven(Clause,i,Atom,ShIndex,
+						 OrdPara,MaxPara,Unit,
+						 Flags, Precedence),
+			Result);
+  
+  return Result;
+}
+
+
+LIST inf_GenSuperpositionRight(CLAUSE GivenClause, SHARED_INDEX ShIndex,
+			       BOOL OrdPara, BOOL MaxPara, BOOL Unit,
+			       FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause and an Index, usually the WorkedOffIndex,
+           three boolean flags for controlling inference
+           preconditions, a flag store and a precedence.
+  RETURNS: A list of clauses derivable from the given clause by 
+           superposition right wrt. the Index.
+
+	   OrdPara=TRUE, MaxPara=TRUE 
+	   -> Superposition Right
+
+	   OrdPara=TRUE, MaxPara=FALSE
+	   -> ordered Paramodulation
+
+	   OrdPara=FALSE, MaxPara=FALSE
+	   -> simple Paramodulation
+
+	   OrdPara=FALSE, MaxPara=TRUE
+	   -> not defined
+
+	   If <Unit>==TRUE the clause with the maximal equality 
+	   additionally must be a unit clause.
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{
+  LIST    Result;
+  TERM    Atom;
+  CLAUSE  Copy;
+  int     i, n;
+  LITERAL ActLit;
+
+#ifdef CHECK
+  if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_GenSuperpositionRight: Illegal input.");
+    misc_FinishErrorReport();
+  }
+  if (!OrdPara && MaxPara) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_GenSuperpositionRight: Illegal inference");
+    misc_ErrorReport("\n rule selection, OrdPara=FALSE & MaxPara=TRUE.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (clause_GetFlag(GivenClause,CLAUSESELECT) ||
+      clause_HasEmptySuccedent(GivenClause) ||
+      !clause_HasSolvedConstraint(GivenClause))
+    return list_Nil();
+
+  Result = list_Nil();
+
+  Copy = clause_Copy(GivenClause);
+  n    = clause_LastSuccedentLitIndex(Copy);
+  
+  for (i = clause_FirstSuccedentLitIndex(Copy); i <= n; i++) {
+    
+    ActLit = clause_GetLiteral(Copy, i);
+    Atom   = clause_LiteralSignedAtom(ActLit);
+    
+    if (!MaxPara ||
+	clause_LiteralGetFlag(ActLit,STRICTMAXIMAL)) {
+      if (fol_IsEquality(Atom) &&
+	  (!Unit || clause_Length(GivenClause) == 1)) {
+	
+	Result = list_Nconc(inf_GenLitSPRight(Copy, term_FirstArgument(Atom), 
+					      term_SecondArgument(Atom), i,
+					      ShIndex,OrdPara,MaxPara,Flags,
+					      Precedence), 
+			    Result);
+	
+	if (!OrdPara ||
+	    !clause_LiteralIsOrientedEquality(ActLit))
+	  Result = list_Nconc(inf_GenLitSPRight(Copy,
+						term_SecondArgument(Atom), 
+						term_FirstArgument(Atom), i,
+						ShIndex,OrdPara,MaxPara,Flags,
+						Precedence),
+			      Result);
+      }
+      if (!clause_GetFlag(Copy, NOPARAINTO))
+	Result = list_Nconc(inf_GenSPRightToGiven(Copy, i, ShIndex, OrdPara,
+						  MaxPara,Unit,Flags,Precedence),
+			    Result);
+    }
+  }
+  clause_Delete(Copy);
+
+  return Result;
+}
+
+
+
+/* END of block with new superposition right rule */
+
+
+static LIST inf_ApplyMParamod(CLAUSE C1, CLAUSE C2, int i, int j, int k,
+			      TERM u_tau, TERM v, TERM s2, TERM t,
+			      TERM v2_sigma, SUBST tau, SUBST rho,
+			      FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   Two clauses, <i> is a literal index in <C1>, <j> and <k>
+           are literal indices in <C2>, <u_tau> with <rho> applied
+	   is used as left side of the two new literals, <v> with
+	   subterm <s2> replaced by <t> is used as right side of
+	   the first new literal, <v2_sigma> as right side of the
+	   second new literal, two substitutions and a flag store.
+	   The substitution <rho> is applied after <tau>.
+	   A flag store.
+	   A precedence.
+  RETURNS: A list containing one clause derived from the given
+           clauses and literals by merging paramodulation.
+  MEMORY:  Memory for the list and the clause is allocated.
+***************************************************************/
+{
+  CLAUSE newClause;
+  TERM   u_sigma;
+  int    m, lc, la, ls, pls, pla, plc, help;
+
+  pls = clause_LastSuccedentLitIndex(C2);
+  pla = clause_LastAntecedentLitIndex(C2);
+  plc = clause_LastConstraintLitIndex(C2);
+
+  ls  = clause_LastSuccedentLitIndex(C1);
+  la  = clause_LastAntecedentLitIndex(C1);
+  lc  = clause_LastConstraintLitIndex(C1);
+
+  newClause = clause_CreateBody(clause_Length(C1) + clause_Length(C2) - 1);
+
+  clause_SetNumOfConsLits(newClause, (clause_NumOfConsLits(C1) +
+				      clause_NumOfConsLits(C2)));
+  clause_SetNumOfAnteLits(newClause, (clause_NumOfAnteLits(C1) +
+				      clause_NumOfAnteLits(C2)));
+  clause_SetNumOfSuccLits(newClause, (clause_NumOfSuccLits(C1) - 1 +
+				      clause_NumOfSuccLits(C2)));
+
+  for (m = clause_FirstLitIndex(); m <= lc; m++)
+    clause_SetLiteral(newClause, m,
+      clause_LiteralCreate(subst_Apply(rho, subst_Apply(tau,
+	term_Copy(clause_GetLiteralTerm(C1, m)))), newClause));
+
+  /* help = number of literals to leave empty */
+  help = clause_NumOfConsLits(C2);
+
+  for ( ; m <= la; m++)
+    clause_SetLiteral(newClause, (m + help),
+      clause_LiteralCreate(subst_Apply(rho, subst_Apply(tau,
+	term_Copy(clause_GetLiteralTerm(C1, m)))), newClause));
+
+  /* help = number of literals to leave empty */
+  help += clause_NumOfAnteLits(C2);
+
+  for ( ; m <= ls; m++) {
+    if (m != i)
+      /* The literal used in the inference isn't copied */
+      clause_SetLiteral(newClause, (m + help), 
+	clause_LiteralCreate(subst_Apply(rho, subst_Apply(tau,
+	  term_Copy(clause_GetLiteralTerm(C1, m)))),newClause));
+    else
+      /* the index has to be decreased to avoid an empty literal! */
+      help--;
+  }
+
+  /* Now we consider the PartnerClause : */
+  
+  /* help = number of already set constraint (Clause) literals */
+  help = clause_NumOfConsLits(C1);
+  
+  for (m = clause_FirstLitIndex(); m <= plc; m++)
+    clause_SetLiteral(newClause, (m + help), 
+      clause_LiteralCreate(subst_Apply(rho, subst_Apply(tau,
+	term_Copy(clause_GetLiteralTerm(C2, m)))),newClause));
+  
+  /* help = number of already set constraint and antecedent Given-literals */
+  help += clause_NumOfAnteLits(C1);
+  
+  for ( ; m <= pla; m++)
+    clause_SetLiteral(newClause, (m + help), 
+      clause_LiteralCreate(subst_Apply(rho, subst_Apply(tau,
+        term_Copy(clause_GetLiteralTerm(C2, m)))),newClause));
+
+  /* help = number of already set literals */
+  help += clause_NumOfSuccLits(C1) - 1;
+  /*help = clause_Length(Clause) - 1;*/
+
+  u_sigma = subst_Apply(rho, term_Copy(u_tau));
+
+  for ( ; m <= pls; m++) {
+    TERM newAtom;
+
+    if (m == j) {
+      /* The first partner literal is modified appropriately! */
+      TERM right;
+      if (v == s2)
+	/* Necessary because term_ReplaceSubtermBy doesn't treat top level */
+	right = term_Copy(t);
+      else {
+	right = term_Copy(v);
+	term_ReplaceSubtermBy(right, s2, t);
+      }		
+      newAtom = term_Create(fol_Equality(), list_Cons(term_Copy(u_sigma),
+		  list_List(subst_Apply(rho, subst_Apply(tau, right)))));
+    } else if (m == k) {
+      /* The second partner lit is modified appropriately!    */
+      newAtom = term_Create(fol_Equality(), list_Cons(term_Copy(u_sigma),
+	          list_List(term_Copy(v2_sigma))));
+    } else {
+      /* Apply substitutions to all other literals */
+      newAtom = subst_Apply(rho, subst_Apply(tau,
+                  term_Copy(clause_GetLiteralTerm(C2, m))));
+    }
+
+    clause_SetLiteral(newClause, (m + help),
+		      clause_LiteralCreate(newAtom, newClause));
+   }
+
+  term_Delete(u_sigma);
+
+  clause_SetFromMergingParamodulation(newClause);
+
+  clause_AddParentClause(newClause, clause_Number(C2));
+  clause_AddParentLiteral(newClause, k);
+  clause_SetDataFromParents(newClause, C2, j, C1, k, Flags, Precedence);
+
+  return list_List(newClause);
+}
+
+
+static LIST inf_Lit2MParamod(CLAUSE C1, CLAUSE C2, int i, int j, TERM s, TERM t,
+			     TERM s2, TERM v, TERM u_tau, SUBST tau,
+			     FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   Two clauses, the index <i> of a strict maximal literal
+           in <C1>, the index <j> of a strict maximal index in <C2>,
+	   <s> and <t> are from literal <i>, <s2> is a subterm
+	   of <v>, <v> is from literal <j>, <u_tau> is <u> with
+	   substitution <tau> applied, a flag store, and a precedence.
+	   <u_tau> must be greater than <v>tau wrt. the ordering.
+  RETURNS: A list of clauses derivable from the given data
+           by merging paramodulation.
+	   This function searches <C2> for a second positive literal
+	   u'=v', where u' is unifiable with <u_tau>.
+  MEMORY:  Memory is allocated for the list and the clauses.
+***************************************************************/
+{
+  LIST result;
+  int  k, last;
+
+  result = list_Nil();
+
+  /* Now find the 3rd literal u' = v' in C2 */
+  last = clause_LastSuccedentLitIndex(C2);  /* Last index */
+  for (k = clause_FirstSuccedentLitIndex(C2); k <= last; k++) {
+    LITERAL partnerLit2  = clause_GetLiteral(C2, k);
+    TERM    partnerAtom2 = clause_LiteralSignedAtom(partnerLit2);
+
+    if (k != j && fol_IsEquality(partnerAtom2)) {
+      /* partnerLit2: u' = v'  or  v' = u' */
+      SUBST      rho;
+      TERM       pLeft2, pRight2, s_sigma, t_sigma, v2_sigma;
+      ord_RESULT ordResult;
+      BOOL       checkPassed;
+
+      pLeft2  = subst_Apply(tau, term_Copy(term_FirstArgument(partnerAtom2)));
+      pRight2 = subst_Apply(tau, term_Copy(term_SecondArgument(partnerAtom2)));
+      
+      /* First try unification with left side */
+      cont_Check();
+
+      if (unify_UnifyCom(cont_LeftContext(), u_tau, pLeft2)) {
+	subst_ExtractUnifierCom(cont_LeftContext(), &rho);
+
+	s_sigma = t_sigma = (TERM) NULL;
+	checkPassed = TRUE;
+
+	if (!clause_LiteralIsOrientedEquality(clause_GetLiteral(C1,i))) {
+	  s_sigma = subst_Apply(rho, subst_Apply(tau, term_Copy(s)));
+	  t_sigma = subst_Apply(rho, subst_Apply(tau, term_Copy(t)));
+	  ordResult = ord_Compare(s_sigma, t_sigma, Flags, Precedence);
+	  if (ordResult == ord_SmallerThan() || ordResult == ord_Equal())
+	    checkPassed = FALSE;
+	}
+
+	if (checkPassed && inf_LiteralsMaxWith2Subst(C1,i,C2,j,rho,tau,
+						     Flags, Precedence)) {
+	  v2_sigma = subst_Apply(rho, term_Copy(pRight2));
+	  result = list_Nconc(inf_ApplyMParamod(C1,C2,i,j,k,u_tau,v,s2,
+						t,v2_sigma,tau,rho,
+						Flags, Precedence),
+			      result);
+	  term_Delete(v2_sigma);
+	}
+	/* Now cleanup */
+	if (s_sigma != NULL) {      /* Also t_sigma != NULL */
+	  term_Delete(s_sigma);
+	  term_Delete(t_sigma);
+	}
+	subst_Delete(rho);
+      }
+
+      cont_Reset();
+
+      /* Now try unification with right side */
+      if (unify_UnifyCom(cont_LeftContext(), u_tau, pRight2)) {
+	subst_ExtractUnifierCom(cont_LeftContext(), &rho);
+
+	s_sigma = t_sigma = (TERM) NULL;
+	checkPassed = TRUE;
+
+	if (!clause_LiteralIsOrientedEquality(clause_GetLiteral(C1,i))) {
+	  s_sigma = subst_Apply(rho, subst_Apply(tau, term_Copy(s)));
+	  t_sigma = subst_Apply(rho, subst_Apply(tau, term_Copy(t)));
+	  ordResult = ord_Compare(s_sigma, t_sigma, Flags, Precedence);
+	  if (ordResult == ord_SmallerThan() || ordResult == ord_Equal())
+	    checkPassed = FALSE;
+	}
+
+	if (checkPassed && inf_LiteralsMaxWith2Subst(C1,i,C2,j,rho,tau,
+						     Flags, Precedence)) {
+	  v2_sigma = subst_Apply(rho, term_Copy(pLeft2));
+	  result = list_Nconc(inf_ApplyMParamod(C1,C2,i,j,k,u_tau,v,s2,
+						t,v2_sigma,tau,rho,
+						Flags, Precedence),
+			      result);
+	  term_Delete(v2_sigma);
+	}
+	/* Now cleanup */
+	if (s_sigma != NULL) {      /* Also t_sigma != NULL */
+	  term_Delete(s_sigma);
+	  term_Delete(t_sigma);
+	}
+	subst_Delete(rho);
+      }
+
+      cont_Reset();
+
+      term_Delete(pLeft2);
+      term_Delete(pRight2);
+    }   /* k != j */
+  }     /* for k */
+  
+  return result;
+}  
+  
+
+static LIST inf_LitMParamod(CLAUSE Clause, int i, BOOL Turn,
+			    SHARED_INDEX ShIndex, FLAGSTORE Flags,
+			    PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause with a strict maximal equality literal at 
+           position <i>, a boolean value, a shared index, a 
+	   flag store and a precedence.
+	   If <Turn> is TRUE, the left and right term of the
+	   equality are exchanged.
+  RETURNS: A list of clauses derivable from the given clause
+           by merging paramodulation.
+	   This function searches a second clause with at least
+	   two positive equalities, where the first equation
+	   has a subterm s', that is unifiable with the left
+	   (or right) side of the given equation.
+***************************************************************/
+{
+  LIST    result, unifiers, literals;
+  LITERAL actLit;
+  TERM    s, t, help;
+
+  actLit = clause_GetLiteral(Clause, i);
+  s      = term_FirstArgument(clause_LiteralSignedAtom(actLit));
+  t      = term_SecondArgument(clause_LiteralSignedAtom(actLit));
+  if (Turn) {
+    /* Exchange s and t */
+    help = s;
+    s    = t;
+    t    = help;
+  }
+  result = list_Nil();
+
+  unifiers = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex),
+			   cont_RightContext(), s);
+  
+  for ( ; !list_Empty(unifiers); unifiers = list_Pop(unifiers)) {
+    TERM s2 = (TERM) list_Car(unifiers);     /* Unifiable with s */
+
+    if (!term_IsVariable(s2) && !term_IsAtom(s2)) {
+      for (literals = sharing_GetDataList(s2, ShIndex);
+	   !list_Empty(literals);
+	   literals = list_Pop(literals)) {
+	LITERAL partnerLit    = (LITERAL) list_Car(literals);  /* u = v[s'] */
+	CLAUSE  partnerClause = clause_LiteralOwningClause(partnerLit);
+	TERM    partnerAtom   = clause_LiteralAtom(partnerLit);
+	int     pli           = clause_LiteralGetIndex(partnerLit);
+
+	if (!clause_GetFlag(partnerClause, CLAUSESELECT) &&
+	    clause_LiteralGetFlag(partnerLit, STRICTMAXIMAL) &&
+	    clause_LiteralIsPositive(partnerLit) &&   /* succedent literal */
+	    clause_LiteralIsEquality(partnerLit) &&
+	    clause_NumOfSuccLits(partnerClause) > 1 && /* > 1 pos. literals */
+	    clause_HasSolvedConstraint(partnerClause)) {
+	  TERM partnerLeft    = term_FirstArgument(partnerAtom);
+	  TERM partnerRight   = term_SecondArgument(partnerAtom);
+	  BOOL inPartnerRight = term_HasPointerSubterm(partnerRight, s2);
+
+	  if (!clause_LiteralIsOrientedEquality(partnerLit) || inPartnerRight){
+	    /* Don't do this if u=v is oriented and s2 is not a subterm of v */
+	    TERM       newPLeft, newPRight;
+	    SUBST      tau;
+	    SYMBOL     partnerMaxVar;
+	    ord_RESULT ordResult;
+
+	    partnerMaxVar = clause_MaxVar(partnerClause);
+	    clause_RenameVarsBiggerThan(Clause, partnerMaxVar);
+	    cont_Check();
+	    unify_UnifyNoOC(cont_LeftContext(), s, cont_RightContext(), s2);
+	    subst_ExtractUnifierCom(cont_LeftContext(), &tau);
+	    cont_Reset();
+
+	    newPLeft  = subst_Apply(tau, term_Copy(partnerLeft));
+	    newPRight = subst_Apply(tau, term_Copy(partnerRight));
+	    if (clause_LiteralIsOrientedEquality(partnerLit))
+	      ordResult = ord_GreaterThan();
+	    else
+	      ordResult = ord_Compare(newPLeft, newPRight, Flags, Precedence);
+
+	    if (inPartnerRight && ord_IsGreaterThan(ordResult)) {
+	      /* Take a look at right side */
+	      result = list_Nconc(inf_Lit2MParamod(Clause,partnerClause,i,pli,
+						   s, t,s2,partnerRight,newPLeft,
+						   tau, Flags, Precedence),
+				  result);
+	    }
+	    if (ord_IsSmallerThan(ordResult) &&
+		(!inPartnerRight || term_HasPointerSubterm(partnerLeft, s2))) {
+	      /* If s2 is not in partnerRight, it MUST be in partnerLeft,
+		 else really do the test */
+	      /* Take a look at left side */
+	      result = list_Nconc(inf_Lit2MParamod(Clause,partnerClause,i,pli,
+						   s,t,s2,partnerLeft,newPRight,
+						   tau,Flags, Precedence),
+				  result);
+	    }
+
+	    term_Delete(newPLeft);
+	    term_Delete(newPRight);
+	    subst_Delete(tau);
+	  }
+	}
+      }  /* for all Literals containing s2 */
+    }    /* if s2 isn't a variable */
+  }      /* for all unifiers s2 */
+
+  return result;
+}
+
+
+static LIST inf_MParamodLitToGiven(CLAUSE Clause, int j, BOOL Turn,
+				   SHARED_INDEX ShIndex, FLAGSTORE Flags,
+				   PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause with a strict maximal equality literal at
+           position <j>, a boolean value, a shared index a 
+	   flag store and a precedence.
+	   If <Turn> is TRUE, the left and right term of the
+	   equality are exchanged.
+  RETURNS: A list of clauses derivable from the given clause
+           by merging paramodulation with this literal as second
+	   literal of the rule.
+***************************************************************/
+{
+  LIST    result, unifiers, superterms, literals;
+  LITERAL actLit;
+  TERM    u, v;
+  int     bottom;
+
+  if (clause_NumOfSuccLits(Clause) < 2)
+    return list_Nil();  /* There must be at least two positive literals */
+
+  actLit = clause_GetLiteral(Clause, j);
+  u  = term_FirstArgument(clause_LiteralSignedAtom(actLit));
+  v = term_SecondArgument(clause_LiteralSignedAtom(actLit));
+  if (Turn) {
+    /* Exchange s and t */
+    TERM help = u;
+    u  = v;
+    v = help;
+  }
+  result = list_Nil();
+  bottom = stack_Bottom();
+
+  sharing_PushReverseOnStack(v);  /* Without variables! */
+
+  while (!stack_Empty(bottom)) {
+    TERM s2 = (TERM) stack_PopResult();
+
+    for (unifiers = st_GetUnifier(cont_LeftContext(),sharing_Index(ShIndex),
+				  cont_RightContext(), s2);
+	 !list_Empty(unifiers);
+	 unifiers = list_Pop(unifiers)) {
+      TERM s = (TERM) list_Car(unifiers);
+
+      for (superterms = term_SupertermList(s);
+	   !list_Empty(superterms);
+	   superterms = list_Cdr(superterms)) {
+	TERM partnerAtom = (TERM) list_Car(superterms);
+
+	if (fol_IsEquality(partnerAtom)) {
+	  for (literals = sharing_NAtomDataList(partnerAtom);
+	       !list_Empty(literals);
+	       literals = list_Cdr(literals)) {
+	    LITERAL partnerLit    = (LITERAL) list_Car(literals);
+	    CLAUSE  partnerClause = clause_LiteralOwningClause(partnerLit);
+	    int     i             = clause_LiteralGetIndex(partnerLit);
+
+	    if (!clause_GetFlag(partnerClause,CLAUSESELECT) &&
+		clause_LiteralGetFlag(partnerLit,STRICTMAXIMAL) &&
+		clause_LiteralIsPositive(partnerLit) &&
+		(s == term_FirstArgument(partnerAtom) ||
+		 !clause_LiteralIsOrientedEquality(partnerLit)) &&
+		clause_HasSolvedConstraint(partnerClause) &&
+		clause_Number(partnerClause) != clause_Number(Clause)) {
+	      /* We don't allow self inferences (both clauses having the     */
+	      /* same number) here, because they're already made in function */
+	      /* inf_LitMParamod.                                            */
+	      SYMBOL partnerMaxVar;
+	      SUBST  tau;
+	      TERM   u_tau, v_tau;
+	      BOOL   checkPassed;
+
+	      partnerMaxVar = clause_MaxVar(partnerClause);
+	      clause_RenameVarsBiggerThan(Clause, partnerMaxVar);
+	      cont_Check();
+	      unify_UnifyNoOC(cont_LeftContext(), s, cont_RightContext(), s2);
+	      subst_ExtractUnifierCom(cont_LeftContext(), &tau);
+	      cont_Reset();
+
+	      u_tau = v_tau = (TERM) NULL;
+	      checkPassed = TRUE;
+
+	      /* u_tau must be greater than v_tau */
+	      if (!clause_LiteralIsOrientedEquality(actLit)) {
+		u_tau = subst_Apply(tau, term_Copy(u));
+		v_tau = subst_Apply(tau, term_Copy(v));
+		if (ord_Compare(u_tau, v_tau, Flags, Precedence) != ord_GreaterThan())
+		  checkPassed = FALSE;
+	      }
+
+	      if (checkPassed) {
+		/* u_tau > v_tau */
+		TERM t;
+
+		if (s == term_FirstArgument(partnerAtom))
+		  t = term_SecondArgument(partnerAtom);
+		else
+		  t = term_FirstArgument(partnerAtom);
+		if (u_tau == (TERM)NULL) {
+		  u_tau = subst_Apply(tau, term_Copy(u));
+		  v_tau = subst_Apply(tau, term_Copy(v));
+		}
+
+		result = list_Nconc(inf_Lit2MParamod(partnerClause,Clause,i,j,
+						     s,t,s2,v,u_tau, tau,Flags,
+						     Precedence),
+				    result);
+	      }
+
+	      /* Now cleanup */
+	      if (u_tau != (TERM)NULL) {
+		term_Delete(u_tau);
+		term_Delete(v_tau);
+	      }
+	      subst_Delete(tau);
+	      clause_Normalize(Clause);
+	    }
+	  }
+	}   /* partnerAtom is equality */
+      }
+    }
+  }
+
+  return result;
+}
+
+
+LIST inf_MergingParamodulation(CLAUSE GivenClause, SHARED_INDEX ShIndex,
+			       FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, a shared index, a flag store and a 
+           precedence.
+  RETURNS: A list of clauses derivable from the given clause
+           by merging paramodulation.
+  MEMORY:  Memory is allocated for the list and the clauses.
+***************************************************************/
+{
+  LIST   result;
+  CLAUSE copy;
+  int    last, i;
+  
+#ifdef CHECK
+  if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_MergingParamodulation: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (clause_GetFlag(GivenClause, CLAUSESELECT) ||
+      clause_HasEmptySuccedent(GivenClause) ||
+      !clause_HasSolvedConstraint(GivenClause))
+    return list_Nil();
+
+  result = list_Nil();
+  copy   = clause_Copy(GivenClause);
+  last   = clause_LastSuccedentLitIndex(copy);
+
+  for (i = clause_FirstSuccedentLitIndex(copy); i <= last; i++) {
+    LITERAL actLit = clause_GetLiteral(copy, i);
+    TERM    atom   = clause_LiteralSignedAtom(actLit);
+    
+    if (clause_LiteralGetFlag(actLit, STRICTMAXIMAL) &&
+	fol_IsEquality(atom)) {
+      
+      result = list_Nconc(inf_LitMParamod(copy,i,FALSE,ShIndex,
+					  Flags, Precedence), 
+			  result);
+      /* Assume GivenClause is the second clause of the rule */
+      result = list_Nconc(inf_MParamodLitToGiven(copy,i,FALSE,ShIndex,
+						 Flags, Precedence),
+			  result);
+      
+      if (!clause_LiteralIsOrientedEquality(actLit)) {
+	/* First check rule with left and right side exchanged */
+	result = list_Nconc(inf_LitMParamod(copy, i, TRUE, ShIndex, 
+					    Flags, Precedence),
+			    result);
+	/* Now assume GivenClause is the second clause of the rule */
+	/* Check with sides exchanged */
+	result = list_Nconc(inf_MParamodLitToGiven(copy,i,TRUE,ShIndex,
+						   Flags, Precedence),
+			    result);
+      }
+    }
+  }  /* for */
+  clause_Delete(copy);
+
+  return result;
+}
+
+
+static CLAUSE inf_ApplyGenRes(LITERAL PosLit, LITERAL NegLit, SUBST SubstTermS,
+			      SUBST SubstPartnerTermS, FLAGSTORE Flags, 
+			      PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause to use for Resolution, the index of a 
+           positive non-equality literal, a unifiable literal,
+           the substitutions for the terms to unify, a flag 
+	   store and a precedence.
+  RETURNS: A clause derivable from the literals owning
+           clause by Resolution wrt. the Index.
+  MEMORY:  Memory for the new clause is allocated.
+***************************************************************/
+{
+  CLAUSE NewClause, GivenClause, PartnerClause;
+  int    i,j,lc,la,ls,pi,pls,pla,plc,help,ConNeg,AntNeg; /* p=Partner,l=last */
+
+  PartnerClause = clause_LiteralOwningClause(NegLit);
+  GivenClause   = clause_LiteralOwningClause(PosLit);
+
+  pls = clause_LastSuccedentLitIndex(PartnerClause);
+  pla = clause_LastAntecedentLitIndex(PartnerClause);
+  plc = clause_LastConstraintLitIndex(PartnerClause);
+
+  pi  = clause_LiteralGetIndex(NegLit);
+
+  ls  = clause_LastSuccedentLitIndex(GivenClause);
+  la  = clause_LastAntecedentLitIndex(GivenClause);
+  lc  = clause_LastConstraintLitIndex(GivenClause);
+
+  i   = clause_LiteralGetIndex(PosLit);
+
+  if (pi <= plc) {
+    ConNeg = 1;
+    AntNeg = 0;
+  }
+  else {
+    ConNeg = 0;
+    AntNeg = 1;
+  }
+
+  NewClause = clause_CreateBody((clause_Length(GivenClause) -1) +
+				clause_Length(PartnerClause) -1);
+
+  clause_SetNumOfConsLits(NewClause,
+			    (clause_NumOfConsLits(GivenClause) +
+			     (clause_NumOfConsLits(PartnerClause)-ConNeg)));
+  
+  clause_SetNumOfAnteLits(NewClause,
+			    (clause_NumOfAnteLits(GivenClause) +
+			     (clause_NumOfAnteLits(PartnerClause)-AntNeg)));
+  
+  clause_SetNumOfSuccLits(NewClause,
+			  ((clause_NumOfSuccLits(GivenClause) -1)+
+			   clause_NumOfSuccLits(PartnerClause)));
+
+
+  /* First set the literals from the GivenClause : */
+  for (j = clause_FirstLitIndex(); j <= lc; j++) {
+    clause_SetLiteral(NewClause, j, 
+      clause_LiteralCreate(subst_Apply(SubstTermS,
+	term_Copy(clause_GetLiteralTerm(GivenClause, j))),NewClause));
+  }
+
+  /* help = number of literals to leave empty */
+  help = clause_NumOfConsLits(PartnerClause)-ConNeg;
+    
+  for ( ; j <= la; j++) {
+    clause_SetLiteral(NewClause, (j + help), 
+      clause_LiteralCreate(subst_Apply(SubstTermS,
+	term_Copy(clause_GetLiteralTerm(GivenClause, j))),NewClause));
+  }
+
+  /* help = number of literals to leave empty */
+  help += clause_NumOfAnteLits(PartnerClause)-AntNeg;
+    
+  
+
+  for ( ; j <= ls; j++) {
+    if (j != i) {
+      /* The ActLit isn't copied! */
+      clause_SetLiteral(NewClause, (j + help), 
+	clause_LiteralCreate(subst_Apply(SubstTermS,
+	  term_Copy(clause_GetLiteralTerm(GivenClause, j))),NewClause));
+
+    } else {
+      /*the index has to be decreased to avoid an empty literal! */
+      help--;
+    }
+  }
+
+  /* Now we consider the PartnerClause : */
+
+  /* help = number of already set constraint (GivenClause-) literals */
+  help = clause_NumOfConsLits(GivenClause);
+
+  for (j = clause_FirstLitIndex(); j <= plc; j++) {
+    if (j != pi) {
+    clause_SetLiteral(NewClause, (j + help), 
+      clause_LiteralCreate(subst_Apply(SubstPartnerTermS,
+	term_Copy(clause_GetLiteralTerm(PartnerClause, j))),NewClause));
+    } else {
+      help--;
+    }
+  }
+
+  /* help = number of already set constraint and antecedent Given-literals */
+  help += clause_NumOfAnteLits(GivenClause);
+
+  for ( ; j <= pla; j++) {
+
+    if (j != pi) {
+      /* The NegLit isn't copied! */
+      clause_SetLiteral(NewClause, (j + help), 
+	clause_LiteralCreate(subst_Apply(SubstPartnerTermS,
+	  term_Copy(clause_GetLiteralTerm(PartnerClause, j))),NewClause));
+
+    } else {
+      /* The index has to be shifted as above.  */
+      help--;
+    }
+  }
+
+  /* help = number of already set (GivenClause-) literals */
+  help += clause_NumOfSuccLits(GivenClause) - 1;
+
+  for ( ; j <= pls; j++) {
+    clause_SetLiteral(NewClause, (j + help), 
+      clause_LiteralCreate(subst_Apply(SubstPartnerTermS,
+	term_Copy(clause_GetLiteralTerm(PartnerClause, j))),NewClause));
+  } /* end of NewClause creation (last for loop). */
+
+
+  clause_SetDataFromParents(NewClause,PartnerClause,pi,GivenClause,i,
+			    Flags, Precedence);
+  clause_SetFromGeneralResolution(NewClause);
+
+  return(NewClause);
+}
+
+
+LIST inf_GeneralResolution(CLAUSE GivenClause, SHARED_INDEX ShIndex,
+			   BOOL Ordered, BOOL Equations, 
+			   FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause and an Index, usually the WorkedOffIndex,
+           two boolean flags, a flag store and a precedence.
+  RETURNS: A list of clauses derivable from the GivenClause by 
+           GeneralResolution wrt. the Index.
+	   If <Ordered>=TRUE, this function generates ordered
+	   resolution inferences (the literals must be selected or
+	   (strict) maximal), otherwise it generates standard
+	   resolution inferences.
+	   If <Equations>=TRUE, equations are allowed for inferences,
+	   else no inferences with equations are generated. The
+	   default is <Equations>=FALSE..
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{
+  CLAUSE GivenCopy;
+  LIST Result;
+  LITERAL ActLit;
+  TERM Atom;
+  int i,n;
+
+#ifdef CHECK
+  if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_GeneralResolution: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (!clause_HasSolvedConstraint(GivenClause))
+    return list_Nil();
+  
+  Result = list_Nil();
+  GivenCopy = clause_Copy(GivenClause);
+  
+  if (clause_GetFlag(GivenCopy,CLAUSESELECT))
+    n = clause_LastAntecedentLitIndex(GivenCopy);
+  else
+    n = clause_LastSuccedentLitIndex(GivenCopy);
+  
+  for (i = clause_FirstAntecedentLitIndex(GivenCopy); i <= n; i++) {
+    
+    ActLit = clause_GetLiteral(GivenCopy, i);
+    Atom   = clause_LiteralAtom(ActLit);
+    
+    if ((Equations || !fol_IsEquality(Atom)) &&
+	(clause_LiteralGetFlag(ActLit,LITSELECT) ||
+	 (!clause_GetFlag(GivenCopy,CLAUSESELECT) &&
+	  (!Ordered || clause_LiteralIsMaximal(ActLit)))) &&	
+	(!Ordered || clause_LiteralIsFromAntecedent(ActLit) || 
+	 clause_LiteralGetFlag(ActLit,STRICTMAXIMAL))) {
+      /* Positive literals must be strict maximal for ORe,     */
+      /* negative literals must be either selected or maximal. */
+      LIST TermList;
+      BOOL Swapped;
+
+      Swapped = FALSE;
+
+      /* The 'endless' loop may run twice for equations, once for other atoms */
+      while (TRUE) {
+	TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex),
+				 cont_RightContext(), Atom);
+	
+	for ( ; !list_Empty(TermList); TermList = list_Pop(TermList)) {
+	  LIST LitList;
+	  TERM PartnerAtom;
+	  
+	  PartnerAtom = list_First(TermList);
+	  
+	  if (!term_IsVariable(PartnerAtom)) {	  
+	    LITERAL PartnerLit;
+	    int     j;
+	    CLAUSE  PartnerClause;
+	    
+	    for (LitList =  sharing_NAtomDataList(PartnerAtom); 
+		 !list_Empty(LitList);  LitList = list_Cdr(LitList)) {
+	      PartnerLit    = list_Car(LitList);
+	      j             = clause_LiteralGetIndex(PartnerLit);
+	      PartnerClause = clause_LiteralOwningClause(PartnerLit);
+	      
+	      if (clause_LiteralsAreComplementary(PartnerLit,ActLit) &&
+		  clause_HasSolvedConstraint(PartnerClause) &&
+		  /* Negative literals must be from the antecedent */
+		  (clause_LiteralIsPositive(PartnerLit) ||
+		   clause_LiteralIsFromAntecedent(PartnerLit)) &&
+		  /* Check whether literal is selected or maximal */
+		  (clause_LiteralGetFlag(PartnerLit,LITSELECT) ||
+		   (!clause_GetFlag(PartnerClause,CLAUSESELECT) &&
+		    (!Ordered || clause_LiteralIsMaximal(PartnerLit)))) &&
+		  /* Positive literals must be strict maximal for ORe */ 
+		  (!Ordered || clause_LiteralIsNegative(PartnerLit) || 
+		   clause_LiteralGetFlag(PartnerLit,STRICTMAXIMAL)) &&
+		  /* Avoid duplicate self-inferences */
+		  (clause_LiteralIsPositive(PartnerLit) ||
+		   clause_Number(GivenClause) != clause_Number(PartnerClause))) {
+		SUBST  Subst, PartnerSubst;
+		SYMBOL MaxVar;
+		
+		MaxVar = clause_MaxVar(PartnerClause);
+		clause_RenameVarsBiggerThan(GivenCopy, MaxVar);
+
+		cont_Check();
+		if (!unify_UnifyNoOC(cont_LeftContext(), Atom, cont_RightContext(),
+				     PartnerAtom)) {
+		  misc_StartErrorReport();
+		  misc_ErrorReport("\n In inf_GeneralResolution: Unification failed.");
+		  misc_FinishErrorReport();
+		}
+		subst_ExtractUnifier(cont_LeftContext(), &Subst,
+				     cont_RightContext(), &PartnerSubst);
+		cont_Reset();
+		
+		if (!Ordered ||
+		    inf_LiteralsMax(GivenCopy, i, Subst, PartnerClause, j,
+				    PartnerSubst, Flags, Precedence)) {
+		  if (clause_LiteralIsNegative(PartnerLit))
+		    Result = list_Cons(inf_ApplyGenRes(ActLit,PartnerLit,Subst,
+						       PartnerSubst,
+						       Flags, Precedence),
+				       Result);
+		  else
+		    Result = list_Cons(inf_ApplyGenRes(PartnerLit, ActLit, 
+						       PartnerSubst,Subst,
+						       Flags, Precedence),
+				       Result);
+		}
+		subst_Delete(Subst);
+		subst_Delete(PartnerSubst);
+	      }
+	    } /* end of for (LitList = sharing_NAtomDataList ...). */
+	  } /* end of if (!term_IsVariable(PartnerAtom)). */
+	} /* end of for (TermList = st_GetUnifier...). */
+	if (!Swapped && fol_IsEquality(Atom)) {
+	  term_EqualitySwap(Atom);         /* Atom is from copied clause */
+	  Swapped = TRUE;
+	} else
+	  break;
+      } /* end of 'endless' loop */
+    } /* end of if (clause_LiteralIsMaximal(ActLit)). */
+  } /* end of for 'all antecedent and succedent literals'. */
+  
+  clause_Delete(GivenCopy);
+  
+  return Result;
+}
+
+
+LIST inf_UnitResolution(CLAUSE GivenClause, SHARED_INDEX ShIndex,
+			BOOL Equations, FLAGSTORE Flags,
+			PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause and an Index, usually the WorkedOffIndex,
+           a boolean flag, a flag store and a precedence.
+  RETURNS: A list of clauses derivable from the Givenclause by 
+           Unit Resolution wrt. the Index.
+	   This function does the same inferences as standard resolution,
+	   except that at least one of the clauses must be a unit clause.
+	   The involved literals don't have to be maximal.
+	   If <Equations>=TRUE, equations are allowed for inferences,
+	   else no inferences with equations are made. The
+	   default is <Equations>=FALSE..
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{
+  CLAUSE   GivenCopy;
+  LIST     Result;
+  LITERAL  ActLit;
+  TERM     Atom;
+  BOOL     GivenIsUnit;
+  int      i,n;
+
+#ifdef CHECK
+  if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_UnitResolution: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (!clause_HasSolvedConstraint(GivenClause))
+    return list_Nil();
+    
+  Result = list_Nil();
+  
+  GivenCopy   = clause_Copy(GivenClause);
+  GivenIsUnit = (clause_Length(GivenCopy) == 1);
+  
+  if (clause_GetFlag(GivenCopy,CLAUSESELECT))
+    n = clause_LastAntecedentLitIndex(GivenCopy);
+  else
+    n = clause_LastSuccedentLitIndex(GivenCopy);
+  
+  for (i=clause_FirstAntecedentLitIndex(GivenCopy); i <= n; i++) {
+    
+    ActLit = clause_GetLiteral(GivenCopy, i);
+    Atom   = clause_LiteralAtom(ActLit);
+    
+    if ((Equations || !fol_IsEquality(Atom)) &&
+	(clause_LiteralGetFlag(ActLit,LITSELECT) ||
+	 !clause_GetFlag(GivenCopy,CLAUSESELECT))) {
+      LIST TermList;
+      BOOL Swapped;
+      
+      Swapped = FALSE;
+
+      /* The 'endless' loop runs twice for equations, once for other atoms */
+      while (TRUE) {
+	TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex),
+				 cont_RightContext(), Atom);
+	
+	for ( ; !list_Empty(TermList); TermList = list_Pop(TermList)) {
+	  LIST LitList;
+	  TERM PartnerAtom;
+	  
+	  PartnerAtom = list_First(TermList);
+	  
+	  if (!term_IsVariable(PartnerAtom)) {
+	    LITERAL PartnerLit;
+	    CLAUSE  PartnerClause;
+	    
+	    for (LitList =  sharing_NAtomDataList(PartnerAtom); 
+		 !list_Empty(LitList);  LitList = list_Cdr(LitList)) {
+	      PartnerLit    = list_Car(LitList);
+	      PartnerClause = clause_LiteralOwningClause(PartnerLit);
+	      
+	      if ((GivenIsUnit || clause_Length(PartnerClause) == 1) &&
+		  clause_LiteralsAreComplementary(PartnerLit,ActLit) &&
+		  clause_HasSolvedConstraint(PartnerClause) &&
+		  /* Negative literals must be from the antecedent */
+		  (clause_LiteralIsPositive(PartnerLit) ||
+		   clause_LiteralIsFromAntecedent(PartnerLit)) &&
+		  /* Either the literal is selected or no literal is selected */
+		  (clause_LiteralGetFlag(PartnerLit,LITSELECT) ||
+		   !clause_GetFlag(PartnerClause,CLAUSESELECT))) {
+		/* Self-inferences aren't possible, since then the clause must */
+		/* be a unit and a single literal can't be both positive and   */
+		/* negative.                                                   */
+		SUBST  Subst, PartnerSubst;
+		SYMBOL MaxVar;
+		
+		MaxVar = clause_MaxVar(PartnerClause);
+		clause_RenameVarsBiggerThan(GivenCopy, MaxVar);
+		
+		cont_Check();
+		if (!unify_UnifyNoOC(cont_LeftContext(), Atom,
+				     cont_RightContext(), PartnerAtom)) {
+		  misc_StartErrorReport();
+		  misc_ErrorReport("\n In inf_UnitResolution: Unification failed.");
+		  misc_FinishErrorReport();
+		}
+		subst_ExtractUnifier(cont_LeftContext(), &Subst,
+				     cont_RightContext(), &PartnerSubst);
+		cont_Reset();
+		
+		if (clause_LiteralIsNegative(PartnerLit))
+		  Result = list_Cons(inf_ApplyGenRes(ActLit, PartnerLit, Subst,
+						     PartnerSubst,
+						     Flags, Precedence),
+				     Result);
+		else
+		  Result = list_Cons(inf_ApplyGenRes(PartnerLit, ActLit, 
+						     PartnerSubst,Subst,
+						     Flags, Precedence),
+				     Result);
+		subst_Delete(Subst);
+		subst_Delete(PartnerSubst);
+	      }
+	    } /* end of for (LitList = sharing_NAtomDataList ...). */
+	  } /* end of if (!term_IsVariable(PartnerAtom)). */
+	} /* end of for (TermList = st_GetUnifier...). */
+	if (!Swapped && fol_IsEquality(Atom)) {
+	  term_EqualitySwap(Atom);        /* Atom is from copied clause */
+	  Swapped = TRUE;
+	} else
+	  break;
+      } /* end of 'endless' loop */
+    } /* end of if (clause_LiteralIsMaximal(ActLit)). */
+  } /* end of for 'all antecedent and succedent literals'. */
+  
+  clause_Delete(GivenCopy);
+  
+  return Result;
+}
+
+LIST inf_BoundedDepthUnitResolution(CLAUSE GivenClause, SHARED_INDEX ShIndex,
+				    BOOL ConClause, FLAGSTORE Flags,
+				    PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause and an Index, usually the WorkedOffIndex,
+           a flag indicating whether the partner clause must be
+	   a conjecture clause, a flag store and a precedence.
+  RETURNS: A list of clauses derivable from the Givenclause by 
+           bounded depth unit resolution wrt. the Index.
+	   This acts similar to inf_UnitResolution, except that
+	   it limits the depth of resolvents to the maximum 
+	   depth of its parent clauses.
+  MEMORY:  A list of clauses is produced, where memory for the 
+           list and the clauses is allocated.
+***************************************************************/
+     /* GivenClause is always a CONCLAUSE */
+{
+  CLAUSE  GivenCopy;
+  LIST    Result;
+  LITERAL ActLit;
+  TERM    Atom;
+  int     i,n,depth;
+
+#ifdef CHECK
+  if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_BoundedDepthUnitResolution: Illegal input.");
+    misc_FinishErrorReport();
+  }
+  cont_Check();
+#endif
+
+  Result    = list_Nil();
+  GivenCopy = clause_Copy(GivenClause);
+  n         = clause_LastLitIndex(GivenCopy);
+  depth     = clause_ComputeTermDepth(GivenCopy);
+
+  for (i = clause_FirstLitIndex(); i <= n; i++) {
+    LIST TermList;
+    BOOL Swapped;
+
+    ActLit   = clause_GetLiteral(GivenCopy, i);
+    Atom     = clause_LiteralAtom(ActLit);
+    Swapped  = FALSE;
+
+    /* The 'endless' loop runs twice for equations, once for other atoms */
+    while (TRUE) {
+      TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex),
+			       cont_RightContext(), Atom);
+
+      for ( ; !list_Empty(TermList); TermList = list_Pop(TermList)) {
+	LIST LitList;
+	TERM PartnerAtom;
+	
+	PartnerAtom = list_First(TermList);
+	
+	if (!term_IsVariable(PartnerAtom)) {
+	  LITERAL PartnerLit;
+	  CLAUSE  PartnerClause;
+	  
+	  for (LitList = sharing_NAtomDataList(PartnerAtom);
+	       !list_Empty(LitList); LitList = list_Cdr(LitList)) {
+	    PartnerLit    = list_Car(LitList);
+	    PartnerClause = clause_LiteralOwningClause(PartnerLit);
+	    
+	    if (clause_LiteralsAreComplementary(PartnerLit,ActLit) &&
+		(clause_Length(GivenCopy)==1 || clause_Length(PartnerClause)==1) &&
+		(clause_GetFlag(GivenCopy,CONCLAUSE) ||
+		 clause_GetFlag(PartnerClause,CONCLAUSE)) &&
+		(!ConClause || clause_GetFlag(PartnerClause,CONCLAUSE))) {
+	      SUBST  Subst, PartnerSubst;
+	      SYMBOL MaxVar;
+	      int    maxdepth;
+	      CLAUSE Resolvent;
+	      
+	      maxdepth = misc_Max(depth, clause_ComputeTermDepth(PartnerClause));
+	      MaxVar   = clause_MaxVar(PartnerClause);
+	      clause_RenameVarsBiggerThan(GivenCopy, MaxVar);
+	      
+	      cont_Check();
+	      if (!unify_UnifyNoOC(cont_LeftContext(), Atom,
+				   cont_RightContext(), PartnerAtom)) {
+		misc_StartErrorReport();
+		misc_ErrorReport("\n In inf_BoundedDepthUnitResolution: Unification failed.");
+		misc_FinishErrorReport();
+	      }
+	      subst_ExtractUnifier(cont_LeftContext(), &Subst,
+				   cont_RightContext(), &PartnerSubst);
+	      cont_Reset();
+	      
+	      if (clause_LiteralIsNegative(PartnerLit))
+		Resolvent = inf_ApplyGenRes(ActLit, PartnerLit, Subst,
+					    PartnerSubst, Flags, Precedence);
+	      else
+		Resolvent = inf_ApplyGenRes(PartnerLit, ActLit, PartnerSubst,
+					    Subst, Flags, Precedence);
+
+	      if (clause_ComputeTermDepth(Resolvent) > maxdepth)
+		clause_Delete(Resolvent);
+	      else {
+		Result = list_Cons(Resolvent,Result);
+	      }
+	      subst_Delete(Subst);
+	      subst_Delete(PartnerSubst);
+	    }
+	  }
+	}
+      }
+      if (!Swapped && fol_IsEquality(Atom)) {
+	term_EqualitySwap(Atom);              /* Given Clause is a copy */
+	Swapped = TRUE;
+      } else
+	break;
+    } /* end of 'endless' loop */ 
+  }
+
+  clause_Delete(GivenCopy);
+
+  return(Result);
+}
+
+static CLAUSE inf_ApplyGeneralFactoring(CLAUSE Clause, NAT i, NAT j,
+					SUBST Subst, FLAGSTORE Flags,
+					PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause an index in the clause, a substitution a 
+           flag store and a precedence.
+  RETURNS: A new clause obtained from <Clause> by applying <Subst>
+           and deleting literal <j> keeping literal <i>
+***************************************************************/
+{
+  CLAUSE NewClause;
+
+  NewClause = clause_Copy(Clause);
+  clause_ClearFlags(NewClause);
+  clause_SubstApply(Subst, NewClause); 
+
+  clause_DeleteLiteral(NewClause, i, Flags, Precedence);
+
+  list_Delete(clause_ParentClauses(NewClause)); 
+  list_Delete(clause_ParentLiterals(NewClause));
+  clause_SetParentLiterals(NewClause,list_Nil());
+  clause_SetParentClauses(NewClause,list_Nil());
+
+  clause_SetDataFromFather(NewClause, Clause, j, Flags, Precedence);
+  clause_SetFromGeneralFactoring(NewClause);
+
+  clause_AddParentClause(NewClause, clause_Number(Clause));
+  clause_AddParentLiteral(NewClause, i);
+
+  clause_NewNumber(NewClause);
+
+  return NewClause;
+}
+
+
+LIST inf_GeneralFactoring(CLAUSE GivenClause, BOOL Ordered, BOOL Left,
+			  BOOL Equations, FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, three boolean flags, a flag store and a
+           precedence.
+           If <Ordered>=TRUE, this function generates ordered
+	   factoring inferences, otherwise standard factoring
+	   inferences.
+	   If <Left> is FALSE, this function only makes factoring
+	   right inferences, otherwise it also makes factoring left
+	   inferences.
+	   If <Equations>=TRUE, equations are allowed for inferences,
+	   else no inferences with equations are generated. The
+	   default is <Equations>=TRUE.
+  RETURNS: A list of clauses derivable from <GivenClause> by GF.
+***************************************************************/
+{
+  LIST    Result;
+  LITERAL ActLit;
+  int     i,j,last;
+
+#ifdef CHECK
+  if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_GeneralFactoring: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (!clause_HasSolvedConstraint(GivenClause))
+    return list_Nil();
+
+  Result = list_Nil();
+
+  /* Always try Factoring Right inferences */
+  last = clause_LastSuccedentLitIndex(GivenClause);
+  if (!clause_GetFlag(GivenClause,CLAUSESELECT)) {
+    for (i = clause_FirstSuccedentLitIndex(GivenClause); i <= last; i++) {
+      ActLit = clause_GetLiteral(GivenClause, i);
+      if ((!Ordered || clause_LiteralIsMaximal(ActLit)) &&
+	  (Equations || !clause_LiteralIsEquality(ActLit))) {
+	TERM    Atom, PartnerAtom;
+	LITERAL PartnerLit;
+	Atom = clause_LiteralAtom(ActLit);
+	for (j = clause_FirstSuccedentLitIndex(GivenClause); j <= last; j++) {
+	  if (i != j) {
+	    PartnerLit = clause_GetLiteral(GivenClause, j);
+	    PartnerAtom = clause_LiteralAtom(PartnerLit);
+	    if ((j>i ||(Ordered && !clause_LiteralIsMaximal(PartnerLit))) &&
+		term_EqualTopSymbols(Atom, PartnerAtom)) {
+	      /* This condition avoids duplicate inferences */
+	      cont_Check();
+	      if (unify_UnifyCom(cont_LeftContext(), Atom, PartnerAtom)) {
+		SUBST mgu;
+		subst_ExtractUnifierCom(cont_LeftContext(), &mgu);
+		if (!Ordered || inf_LitMax(GivenClause,i,j,mgu,FALSE,
+					   Flags, Precedence))
+		  Result = list_Cons(inf_ApplyGeneralFactoring(GivenClause,i,j,
+							       mgu,Flags, 
+							       Precedence),
+				     Result);
+		subst_Delete(mgu);
+	      }
+	      cont_Reset();
+	      if (fol_IsEquality(Atom) &&  /* PartnerAtom is equality, too */
+		  unify_UnifyCom(cont_LeftContext(),
+				 term_SecondArgument(Atom), 
+				 term_FirstArgument(PartnerAtom)) &&
+		  unify_UnifyCom(cont_LeftContext(),
+				 term_FirstArgument(Atom), 
+				 term_SecondArgument(PartnerAtom))) {
+		SUBST mgu;
+		subst_ExtractUnifierCom(cont_LeftContext(), &mgu);
+		if (!Ordered || inf_LitMax(GivenClause,i,j,mgu,FALSE,
+					   Flags, Precedence))
+		  Result = list_Cons(inf_ApplyGeneralFactoring(GivenClause,i,j,
+							       mgu,Flags, 
+							       Precedence),
+				     Result);
+		subst_Delete(mgu);
+	      }
+	      cont_Reset();
+	    }
+	  } 
+	}
+      }
+    }
+  }
+  /* Try Factoring Left inferences only if <Left>==TRUE */
+  if (Left) {
+    last = clause_LastAntecedentLitIndex(GivenClause);
+    for (i = clause_FirstAntecedentLitIndex(GivenClause); i <= last; i++) {
+      ActLit = clause_GetLiteral(GivenClause, i);
+      if ((Equations || !clause_LiteralIsEquality(ActLit)) &&
+	  (clause_LiteralGetFlag(ActLit,LITSELECT) ||
+	   (!clause_GetFlag(GivenClause,CLAUSESELECT) &&
+	    (!Ordered || clause_LiteralIsMaximal(ActLit))))) {
+	TERM    Atom, PartnerAtom;
+	LITERAL PartnerLit;
+	Atom = clause_LiteralAtom(ActLit);
+	for (j = clause_FirstAntecedentLitIndex(GivenClause);j <= last; j++) {
+	  if (i != j) {
+	    PartnerLit = clause_GetLiteral(GivenClause, j);
+	    PartnerAtom = clause_LiteralAtom(PartnerLit);
+	    /* In order to avoid duplicate inferences, we do the following  */
+	    /* somewhat "tricky" test. What we want is something like       */
+	    /* "if (j>i || j wasn't considered within the outer loop) {...} */
+	    /* This lengthy condition can be transformed into the following */
+	    /* condition, because only one negative literal is selected.    */
+	    /* This implies that the literal at index j can't be selected.  */
+	    if ((j>i || clause_LiteralGetFlag(ActLit,LITSELECT) ||
+		(Ordered && !clause_LiteralIsMaximal(PartnerLit))) &&
+		term_EqualTopSymbols(Atom, PartnerAtom)) {
+	      PartnerAtom = clause_LiteralAtom(PartnerLit);
+	      cont_Check();
+	      if (unify_UnifyCom(cont_LeftContext(), Atom, PartnerAtom)) {
+		SUBST mgu;
+		subst_ExtractUnifierCom(cont_LeftContext(), &mgu);
+		if (!Ordered || clause_LiteralGetFlag(ActLit,LITSELECT) ||
+		    inf_LitMax(GivenClause,i,j,mgu,FALSE,Flags, Precedence))
+		  Result = list_Cons(inf_ApplyGeneralFactoring(GivenClause,i,j,
+							       mgu,Flags,
+							       Precedence),
+				     Result);
+		subst_Delete(mgu);
+	      }
+	      cont_Reset();
+	      if (fol_IsEquality(Atom) && /* PartnerAtom is equality, too */
+		  unify_UnifyCom(cont_LeftContext(),
+				 term_SecondArgument(Atom), 
+				 term_FirstArgument(PartnerAtom)) &&
+		  unify_UnifyCom(cont_LeftContext(),
+				 term_FirstArgument(Atom), 
+				 term_SecondArgument(PartnerAtom))) {
+		SUBST mgu;
+		subst_ExtractUnifierCom(cont_LeftContext(), &mgu);
+		if (!Ordered || clause_LiteralGetFlag(ActLit,LITSELECT) ||
+		    inf_LitMax(GivenClause,i,j,mgu,FALSE,Flags, Precedence))
+		  Result = list_Cons(inf_ApplyGeneralFactoring(GivenClause,i,j,
+							       mgu,Flags,
+							       Precedence),
+				     Result);
+		subst_Delete(mgu);
+	      }
+	      cont_Reset();
+	    }
+	  } 
+	}
+      }
+    }
+  }
+  cont_Check();
+
+  return Result;
+}
+
+
+/***************************************************************/
+/* START of code for new Superposition Left rule               */
+/***************************************************************/
+
+
+static LIST inf_GenLitSPLeft(CLAUSE Clause, TERM Left, TERM Right, int i,
+			     SHARED_INDEX ShIndex,BOOL OrdPara, BOOL MaxPara,
+			     FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause (unshared) with a positive equality literal
+           at position <i> where <Left> and <Right> are the 
+	   arguments of just that literal, two boolean flags, 
+	   a flag store and a precedence.
+	   For Ordered Paramodulation and Superposition <Right>
+           mustn't be greater wrt. the ordering than <Left>.
+	   For Superposition the literal must be strictly maximal.
+  RETURNS: A list of clauses derivable with the literals owning
+           clause by Superposition Left wrt. the Index.
+  MEMORY:  The list of clauses is extended, where memory for the
+           list and the clauses is allocated.
+***************************************************************/
+{
+  LIST Result, Terms;
+
+#ifdef CHECK
+  if (clause_GetFlag(Clause, CLAUSESELECT) ||
+      (OrdPara &&
+       clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i)) &&
+       Left == term_SecondArgument(clause_GetLiteralAtom(Clause,i))) ||
+      (MaxPara &&
+       !clause_LiteralGetFlag(clause_GetLiteral(Clause,i), STRICTMAXIMAL))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_GenLitSPLeft: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Result = list_Nil();
+  Terms  = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex),
+			 cont_RightContext(), Left);
+
+  for ( ; !list_Empty(Terms); Terms = list_Pop(Terms)) {
+    LIST Lits;
+    TERM Term;
+
+    Term = (TERM)list_First(Terms);
+
+    if (!term_IsVariable(Term) && !symbol_IsPredicate(term_TopSymbol(Term))) {
+
+      Lits = sharing_GetDataList(Term, ShIndex);
+
+      for ( ; !list_Empty(Lits); Lits = list_Pop(Lits)){
+
+	LITERAL PartnerLit;
+	TERM    PartnerAtom;
+	CLAUSE  PartnerClause;
+	int     pli;
+
+	PartnerLit        = (LITERAL)list_Car(Lits); /* Antecedent Literal ! */
+	PartnerAtom       = clause_LiteralAtom(PartnerLit);  
+	pli               = clause_LiteralGetIndex(PartnerLit);
+	PartnerClause     = clause_LiteralOwningClause(PartnerLit);
+
+	if ((clause_LiteralGetFlag(PartnerLit,LITSELECT) ||
+	     (!clause_GetFlag(PartnerClause,CLAUSESELECT) &&
+	      (!MaxPara || clause_LiteralIsMaximal(PartnerLit)))) &&
+	    clause_LiteralIsNegative(PartnerLit) &&
+	    !clause_GetFlag(PartnerClause,NOPARAINTO) &&
+	    clause_HasSolvedConstraint(PartnerClause)) {
+	  /* If <PartnerClause> has a solved constraint and <PartnerLit> */
+	  /* is negative then <PartnerLit> is from the antecedent.       */
+
+	  SUBST  Subst, PartnerSubst;
+	  TERM   NewLeft,NewRight;
+	  SYMBOL PartnerMaxVar;
+	  TERM   SupAtom; 
+
+	  SupAtom = (TERM)NULL;
+	  PartnerMaxVar = clause_MaxVar(PartnerClause);
+	  NewLeft       = Left;
+	  clause_RenameVarsBiggerThan(Clause, PartnerMaxVar);
+
+	  cont_Check();
+	  unify_UnifyNoOC(cont_LeftContext(), Left, cont_RightContext(), Term);
+	  subst_ExtractUnifier(cont_LeftContext(), &Subst,
+			       cont_RightContext(), &PartnerSubst);
+	  cont_Reset();
+
+	  if (!MaxPara ||
+	      inf_LiteralsMax(Clause, i, Subst, PartnerClause, pli,
+			      PartnerSubst, Flags, Precedence)) {
+	    NewRight = subst_Apply(Subst, term_Copy(Right));
+	    if (OrdPara &&
+		!clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i)))
+	      NewLeft  = subst_Apply(Subst, term_Copy(Left));
+	    if (!OrdPara ||
+		NewLeft == Left ||
+		ord_Compare(NewLeft,NewRight,Flags, Precedence) != ord_SmallerThan()) {
+	      if (!MaxPara || clause_LiteralIsPredicate(PartnerLit)) {
+		SupAtom = inf_AllTermsRplac(PartnerAtom,Term,NewRight,
+					    PartnerSubst);
+	      } else {
+		/* Superposition and <PartnerLit> is equality */
+		if (clause_LiteralIsOrientedEquality(PartnerLit))
+		  SupAtom = inf_AllTermsLeftRplac(PartnerAtom,Term,NewRight,
+						   PartnerSubst);
+		else {
+		  TERM NewPartnerLeft,NewPartnerRight;
+		  NewPartnerLeft  = subst_Apply(PartnerSubst, 
+		       	    term_Copy(term_FirstArgument(PartnerAtom)));
+		  NewPartnerRight = subst_Apply(PartnerSubst, 
+			    term_Copy(term_SecondArgument(PartnerAtom)));
+		  switch (ord_Compare(NewPartnerLeft,NewPartnerRight,
+				      Flags, Precedence)) {
+		  case ord_SMALLER_THAN:
+		    SupAtom = inf_AllTermsRightRplac(PartnerAtom,Term,
+						      NewRight,PartnerSubst);
+		    break;
+		  case ord_GREATER_THAN:
+		    SupAtom = inf_AllTermsLeftRplac(PartnerAtom,Term,
+						     NewRight,PartnerSubst);
+		    break;
+		  default:
+		    SupAtom = inf_AllTermsRplac(PartnerAtom,Term,
+						 NewRight,PartnerSubst);
+		  }
+		  term_Delete(NewPartnerLeft);
+		  term_Delete(NewPartnerRight);
+		}
+	      }
+
+	      if (SupAtom != NULL)
+		Result = list_Cons(inf_ApplyGenSuperposition(Clause, i, Subst, 
+							     PartnerClause, pli,
+							     PartnerSubst, 
+							     SupAtom, FALSE,
+							     OrdPara, MaxPara,
+							     Flags, Precedence),
+				   Result);
+	    }
+	    if (NewLeft != Left)
+	      term_Delete(NewLeft);
+	    term_Delete(NewRight);
+	  }
+	  subst_Delete(Subst);
+	  subst_Delete(PartnerSubst);
+	}
+      }
+    }
+  }
+  return Result;
+}
+
+
+static LIST inf_GenSPLeftEqToGiven(CLAUSE Clause, int i, BOOL Left,
+				   SHARED_INDEX ShIndex, BOOL OrdPara,
+				   BOOL MaxPara, BOOL Unit, FLAGSTORE Flags,
+				   PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   An unshared clause, the index of an antecedent 
+           literal that is an equality literal, a boolean 
+	   value, a shared index, three boolean flags 
+	   controlling inference preconditions, a flag store 
+	   and a precedence.
+           If Left==TRUE then the left argument of the literal is used
+	   otherwise the right argument.
+	   OrdPara and MaxPara control inference conditions.
+	   If <Unit>==TRUE the clause with the maximal, positive
+	   equality must be a unit clause.
+  RETURNS: A list of clauses derivable from generalized 
+           superposition Left on the
+           GivenCopy  wrt. the Index. See GenSuperpositionLeft
+	   for effects of OrdPara and MaxPara
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{
+  LIST    Result, TermList, ParentList;
+  int     Bottom;
+  LITERAL Lit;
+  TERM    Atom, Term, PartnerTerm, PartnerEq;
+
+  Result = list_Nil();
+  Lit    = clause_GetLiteral(Clause,i); /* Is an antecedent Literal ! */
+  Atom   = clause_LiteralAtom(Lit);
+
+#ifdef CHECK
+  if (clause_GetFlag(Clause, NOPARAINTO) ||
+      !clause_LiteralIsEquality(Lit) ||
+      !clause_LiteralIsFromAntecedent(Lit) ||
+      (MaxPara && clause_LiteralIsOrientedEquality(Lit) && !Left) ||
+      (!clause_LiteralGetFlag(clause_GetLiteral(Clause,i),LITSELECT) &&
+       (clause_GetFlag(Clause, CLAUSESELECT) ||
+	(MaxPara && !clause_LiteralIsMaximal(clause_GetLiteral(Clause,i)))))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_GenSPLeftEqToGiven: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Bottom = stack_Bottom();
+  if (Left) 
+    sharing_PushOnStack(term_FirstArgument(Atom));
+  else
+    sharing_PushOnStack(term_SecondArgument(Atom));
+
+  while (!stack_Empty(Bottom)) {
+    Term = (TERM)stack_PopResult();
+    if (!term_IsVariable(Term)) {
+      /* Superposition into variables is not necessary */
+      TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(ShIndex),
+			       cont_RightContext(), Term);
+      for ( ;!list_Empty(TermList); TermList = list_Pop(TermList)) {
+	PartnerTerm = (TERM)list_Car(TermList);
+	for (ParentList = term_SupertermList(PartnerTerm);
+	     !list_Empty(ParentList); ParentList = list_Cdr(ParentList)) {
+	  PartnerEq = (TERM)list_Car(ParentList);
+	  if (fol_IsEquality(PartnerEq)) {
+	    CLAUSE  PartnerClause;
+	    LITERAL PartnerLit;
+	    LIST    Scl;
+	    int     j;
+	    for (Scl = sharing_NAtomDataList(PartnerEq);
+		 !list_Empty(Scl); Scl = list_Cdr(Scl)) {
+	      PartnerLit    = (LITERAL)list_Car(Scl);
+	      j             = clause_LiteralGetIndex(PartnerLit);
+	      PartnerClause = clause_LiteralOwningClause(PartnerLit);
+
+	      if (!clause_GetFlag(PartnerClause,CLAUSESELECT) &&
+		  (!MaxPara ||
+		   clause_LiteralGetFlag(PartnerLit,STRICTMAXIMAL)) &&
+		  (!OrdPara ||
+		   PartnerTerm == term_FirstArgument(PartnerEq) ||
+		   !clause_LiteralIsOrientedEquality(PartnerLit)) &&
+		  clause_LiteralIsPositive(PartnerLit) &&
+		  clause_Number(PartnerClause) != clause_Number(Clause) &&
+		  (!Unit || clause_Length(PartnerClause) == 1) &&
+		  clause_HasSolvedConstraint(PartnerClause)) {
+		SYMBOL MaxVar;
+		SUBST  Subst, PartnerSubst;
+
+		MaxVar      = clause_MaxVar(PartnerClause);
+		clause_RenameVarsBiggerThan(Clause,MaxVar);
+		cont_Check();
+		unify_UnifyNoOC(cont_LeftContext(), Term,
+				cont_RightContext(),PartnerTerm);
+		subst_ExtractUnifier(cont_LeftContext(), &Subst,
+				     cont_RightContext(),&PartnerSubst);
+		cont_Reset();
+		if (!MaxPara ||
+		    inf_LiteralsMax(Clause, i, Subst, PartnerClause, j,
+				    PartnerSubst, Flags, Precedence)) {
+		  TERM PartnerLeft,PartnerRight;
+		  BOOL Check, PartnerCheck;
+		  PartnerLeft = PartnerRight = NULL;
+		  PartnerCheck = Check = TRUE;
+		  if (OrdPara &&
+		      !clause_LiteralIsOrientedEquality(PartnerLit)) {
+		    /* Check post condition for partner literal */
+		    if (PartnerTerm == term_FirstArgument(PartnerEq))
+		      PartnerRight = term_SecondArgument(PartnerEq);
+		    else
+		      PartnerRight = term_FirstArgument(PartnerEq);
+		    PartnerLeft  = subst_Apply(PartnerSubst,
+					       term_Copy(PartnerTerm));
+		    PartnerRight = subst_Apply(PartnerSubst,
+					       term_Copy(PartnerRight));
+		    PartnerCheck = (ord_Compare(PartnerLeft,PartnerRight,
+						Flags, Precedence)
+				    != ord_SmallerThan());
+		  }
+		  if (PartnerCheck &&
+		      MaxPara && !clause_LiteralIsOrientedEquality(Lit)) {
+		    /* Check post condition for literal in given clause */
+		    TERM NewLeft, NewRight;
+		    if (Left) {
+		      NewLeft  = term_FirstArgument(Atom);
+		      NewRight = term_SecondArgument(Atom);
+		    } else {
+		      NewLeft  = term_SecondArgument(Atom);
+		      NewRight = term_FirstArgument(Atom);
+		    }
+		    NewLeft  = subst_Apply(Subst, term_Copy(NewLeft));
+		    NewRight = subst_Apply(Subst, term_Copy(NewRight));
+		    Check = (ord_Compare(NewLeft, NewRight, Flags, Precedence)
+			     != ord_SmallerThan());
+		    term_Delete(NewLeft);
+		    term_Delete(NewRight);
+		  }
+		  if (Check && PartnerCheck) {
+		    /* Make inference only if both tests were successful */
+		    TERM SupAtom;
+		    SupAtom = NULL;
+		    if (PartnerRight == NULL) {
+		      if (PartnerTerm==term_FirstArgument(PartnerEq))
+			PartnerRight = term_SecondArgument(PartnerEq);
+		      else
+			PartnerRight = term_FirstArgument(PartnerEq);
+		      PartnerRight = subst_Apply(PartnerSubst,
+						 term_Copy(PartnerRight));
+		    }
+		    if (Left)
+		      SupAtom = inf_AllTermsLeftRplac(Atom, Term,
+						      PartnerRight, Subst);
+		    else 
+		      SupAtom = inf_AllTermsRightRplac(Atom, Term,
+						       PartnerRight, Subst);
+#ifdef CHECK
+		    if (SupAtom == NULL) {
+		      misc_StartErrorReport();
+		      misc_ErrorReport("\n In inf_GenSPLeftEqToGiven:");
+		      misc_ErrorReport(" replacement wasn't possible.");
+		      misc_FinishErrorReport();
+		    }
+#endif
+		    Result =
+		      list_Cons(inf_ApplyGenSuperposition(PartnerClause, j,
+							  PartnerSubst,Clause,
+							  i,Subst,SupAtom,
+							  FALSE,OrdPara,
+							  MaxPara,Flags,
+							  Precedence), 
+				Result);
+		  }
+		  if (PartnerLeft != term_Null())
+		    term_Delete(PartnerLeft);
+		  if (PartnerRight != term_Null())
+		    term_Delete(PartnerRight);
+		}
+		subst_Delete(Subst);
+		subst_Delete(PartnerSubst);
+	      }
+	    }
+	  }
+	}
+      }
+    }
+  }
+  return Result;
+}
+
+
+static LIST inf_GenSPLeftLitToGiven(CLAUSE Clause, int i, TERM Atom,
+				    SHARED_INDEX ShIndex, BOOL OrdPara,
+				    BOOL MaxPara, BOOL Unit, FLAGSTORE Flags,
+				    PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   An unshared clause, the index of an antecedent 
+           literal that is not an equality literal and its 
+	   atom, a shared index, three boolean flags 
+	   controlling inference preconditions (see also 
+	   inf_GenSuperpositionLeft), a flag store and a
+	   precedence.
+  RETURNS: A list of clauses derivable from superposition left on the
+           GivenCopy  wrt. the Index.
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{
+  LIST    Result, TermList, ParentList;
+  int     Bottom;
+  LITERAL Lit;
+  TERM    Term, PartnerTerm, PartnerEq;
+
+  Result = list_Nil();
+  Lit    = clause_GetLiteral(Clause,i);
+
+#ifdef CHECK
+  if (clause_LiteralIsEquality(Lit) || !clause_LiteralIsFromAntecedent(Lit)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_GenSPLeftLitToGiven: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Bottom = stack_Bottom();
+  sharing_PushListOnStack(term_ArgumentList(Atom));
+
+  while (!stack_Empty(Bottom)) {
+    Term = (TERM)stack_PopResult();
+    if (!term_IsVariable(Term)) {
+      /* Superposition into variables is not necessary */
+      TermList = st_GetUnifier(cont_LeftContext(),
+			       sharing_Index(ShIndex),
+			       cont_RightContext(),
+			       Term);
+      for ( ; !list_Empty(TermList); TermList=list_Pop(TermList)) {
+	PartnerTerm = (TERM)list_Car(TermList);
+	for (ParentList = term_SupertermList(PartnerTerm);
+	     !list_Empty(ParentList); ParentList = list_Cdr(ParentList)) {
+	  PartnerEq = (TERM)list_Car(ParentList);
+	  if (fol_IsEquality(PartnerEq)) {
+	    CLAUSE  PartnerClause;
+	    LITERAL PartnerLit;
+	    TERM    PartnerAtom;
+	    LIST    Scl;
+	    int     j;
+	    for (Scl = sharing_NAtomDataList(PartnerEq);
+		 !list_Empty(Scl); Scl = list_Cdr(Scl)) {
+	      PartnerLit    = (LITERAL)list_Car(Scl);
+	      j             = clause_LiteralGetIndex(PartnerLit);
+	      PartnerClause = clause_LiteralOwningClause(PartnerLit);
+	      PartnerAtom   = clause_LiteralAtom(PartnerLit);
+	      if (!clause_GetFlag(PartnerClause,CLAUSESELECT) &&
+		  (!MaxPara ||
+		   clause_LiteralGetFlag(PartnerLit,STRICTMAXIMAL)) &&
+		  (!OrdPara ||
+		   PartnerTerm == term_FirstArgument(PartnerAtom) ||
+		   !clause_LiteralIsOrientedEquality(PartnerLit)) &&
+		  clause_LiteralIsPositive(PartnerLit) &&
+		  clause_Number(PartnerClause) != clause_Number(Clause) &&
+		  (!Unit || clause_Length(PartnerClause) == 1) &&
+		  clause_HasSolvedConstraint(PartnerClause)) {
+		SYMBOL MaxVar;
+		TERM   PartnerLeft,PartnerRight;
+		SUBST  Subst, PartnerSubst;
+		TERM   SupAtom;
+
+		SupAtom = (TERM)NULL;
+		MaxVar      = clause_MaxVar(PartnerClause);
+		clause_RenameVarsBiggerThan(Clause,MaxVar);
+		cont_Check();
+		unify_UnifyNoOC(cont_LeftContext(),Term,cont_RightContext(),PartnerTerm);
+		subst_ExtractUnifier(cont_LeftContext(),&Subst,cont_RightContext(),&PartnerSubst);
+		cont_Reset();
+		if (!MaxPara ||
+		    inf_LiteralsMax(Clause, i, Subst, PartnerClause, j,
+				     PartnerSubst, Flags, Precedence)) {
+		  PartnerLeft  = subst_Apply(PartnerSubst,
+				 term_Copy(PartnerTerm));
+		  if (PartnerTerm == term_FirstArgument(PartnerAtom))
+		    PartnerRight = subst_Apply(PartnerSubst,
+				 term_Copy(term_SecondArgument(PartnerAtom)));
+		  else
+		    PartnerRight = subst_Apply(PartnerSubst,
+				 term_Copy(term_FirstArgument(PartnerAtom)));
+
+		  if (!OrdPara ||
+		      clause_LiteralIsOrientedEquality(PartnerLit) ||
+		      ord_Compare(PartnerLeft,PartnerRight,Flags, Precedence)
+		      != ord_SmallerThan()) {
+		    SupAtom = inf_AllTermsRplac(Atom,Term,PartnerRight,Subst);
+#ifdef CHECK
+		    if (SupAtom == NULL) {
+		      misc_StartErrorReport();
+		      misc_ErrorReport("\n In inf_GenSPRightLitToGiven:");
+		      misc_ErrorReport(" replacement wasn't possible.");
+		      misc_FinishErrorReport();
+		    }
+#endif
+		    Result =
+		      list_Cons(inf_ApplyGenSuperposition(PartnerClause, j,
+							  PartnerSubst, Clause,
+							  i, Subst, SupAtom,
+							  FALSE, OrdPara,
+							  MaxPara, Flags,
+							  Precedence), 
+				Result);
+
+		  }
+		  term_Delete(PartnerLeft);
+		  term_Delete(PartnerRight);
+		}
+		subst_Delete(Subst);
+		subst_Delete(PartnerSubst);
+	      }
+	    }
+	  }
+	}
+      }
+    }
+  }
+  return Result;
+}
+
+
+static LIST inf_GenSPLeftToGiven(CLAUSE Clause, int i, SHARED_INDEX ShIndex, 
+				 BOOL OrdPara, BOOL MaxPara, BOOL Unit,
+				 FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   An unshared clause, the index of an antecedent
+           literal, an index of shared clauses, three boolean
+	   flags for controlling inference preconditions (see
+	   inf_GenSuperpositionLeft), a flag store and a
+	   precedence.
+  RETURNS: A list of clauses derivable from Superposition Left
+           on the GivenCopy  wrt. the Index.
+  MEMORY:  A list of clauses is produced, where memory for the
+           list and the clauses is allocated.
+***************************************************************/
+{
+  TERM Atom;
+  LIST Result;
+
+#ifdef CHECK
+  if (clause_GetFlag(Clause, NOPARAINTO) ||
+      (!clause_LiteralGetFlag(clause_GetLiteral(Clause,i),LITSELECT) &&
+       (clause_GetFlag(Clause, CLAUSESELECT) ||
+	(MaxPara && !clause_LiteralIsMaximal(clause_GetLiteral(Clause,i)))))) {
+      misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_GenSPLeftToGiven: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Result  = list_Nil();
+  Atom    = clause_LiteralAtom(clause_GetLiteral(Clause,i));
+
+  if (fol_IsEquality(Atom)) {
+    Result = list_Nconc(inf_GenSPLeftEqToGiven(Clause,i, TRUE,ShIndex, OrdPara,
+					       MaxPara, Unit, Flags,Precedence), 
+			Result);
+    if (!MaxPara ||
+	!clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i)))
+      /* For SPm and OPm always try other direction, for SpR try it */
+      /* only if the literal is not oriented.                       */
+      Result = list_Nconc(inf_GenSPLeftEqToGiven(Clause,i,FALSE,ShIndex,OrdPara,
+						 MaxPara,Unit,Flags,Precedence),
+			  Result);
+  } else
+    Result = list_Nconc(inf_GenSPLeftLitToGiven(Clause,i,Atom,ShIndex,OrdPara,
+						MaxPara,Unit,Flags,Precedence),
+			Result);
+
+  return Result;
+}
+
+
+LIST inf_GenSuperpositionLeft(CLAUSE GivenClause, SHARED_INDEX ShIndex, 
+			      BOOL OrdPara, BOOL MaxPara, BOOL Unit,
+			      FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause and an Index, usually the WorkedOffIndex,
+           two boolean flags for controlling inference
+           preconditions, a flag store and a precedence.
+  RETURNS: A list of clauses derivable from the Givenclause by 
+           one of the following inference rules wrt. the Index:
+
+	   OrdPara=TRUE, MaxPara=TRUE 
+	   -> Superposition Left
+
+	   OrdPara=TRUE, MaxPara=FALSE
+	   -> ordered Paramodulation
+
+	   OrdPara=FALSE, MaxPara=FALSE
+	   -> simple Paramodulation
+
+	   OrdPara=FALSE, MaxPara=TRUE
+	   -> not defined
+
+	   If <Unit>==TRUE the clause with the maximal equality 
+	   additionally must be a unit clause.
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{
+  LIST    Result;
+  TERM    Atom;
+  CLAUSE  Copy;
+  int     i, n;
+  LITERAL ActLit;
+
+#ifdef CHECK
+  if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_GenSuperpositionLeft: Illegal input.");
+    misc_FinishErrorReport();
+  }
+  if (!OrdPara && MaxPara) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_GenSuperpositionLeft: Illegal inference rule selection,");
+    misc_ErrorReport("\n OrdPara=FALSE & MaxPara=TRUE.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Result = list_Nil();
+
+  if (!clause_HasSolvedConstraint(GivenClause))
+    return Result;
+  
+  Copy = clause_Copy(GivenClause);
+  n    = clause_LastSuccedentLitIndex(Copy);
+  
+  if (!clause_GetFlag(Copy, CLAUSESELECT) &&
+      (!Unit || clause_Length(Copy) == 1)) {
+    for (i = clause_FirstSuccedentLitIndex(Copy); i <= n; i++) {
+      ActLit = clause_GetLiteral(Copy, i);
+      Atom   = clause_LiteralSignedAtom(ActLit);
+      
+      if (fol_IsEquality(Atom) &&
+	  (!MaxPara ||
+	   clause_LiteralGetFlag(ActLit,STRICTMAXIMAL))) {
+	
+	Result =
+	  list_Nconc(inf_GenLitSPLeft(Copy, term_FirstArgument(Atom), 
+				      term_SecondArgument(Atom), i, ShIndex,
+				      OrdPara, MaxPara, Flags, Precedence), 
+		     Result);
+	if (!OrdPara || !clause_LiteralIsOrientedEquality(ActLit))
+	  /* For SPm always try the other direction, for OPm and SpL */
+	  /* only try it if the literal is not oriented.             */
+	  Result =
+	    list_Nconc(inf_GenLitSPLeft(Copy, term_SecondArgument(Atom), 
+					term_FirstArgument(Atom), i, ShIndex,
+					OrdPara, MaxPara, Flags, Precedence), 
+		       Result);
+      }
+    }
+  }
+
+  n = clause_LastAntecedentLitIndex(Copy);  
+  if (!clause_GetFlag(Copy,NOPARAINTO)) {
+    for (i = clause_FirstAntecedentLitIndex(Copy); i <= n; i++) {
+      ActLit = clause_GetLiteral(Copy, i);
+      
+      if (clause_LiteralGetFlag(ActLit, LITSELECT) ||
+	  (!clause_GetFlag(Copy, CLAUSESELECT) &&
+	   (!MaxPara || clause_LiteralIsMaximal(ActLit))))
+	Result = list_Nconc(inf_GenSPLeftToGiven(Copy, i, ShIndex, OrdPara,
+						 MaxPara,Unit,Flags,Precedence),
+			    Result);
+    }
+  }
+  clause_Delete(Copy);
+
+  return(Result);
+}
+
+
+
+LIST inf_ApplyDefinition(PROOFSEARCH Search, CLAUSE Clause,
+			 FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A proof search object, a clause, a flag store and a
+           precedence.
+  RETURNS: A list of clauses derivable from the given clause by 
+           applying the (potential) definitions in <Search>.
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{
+  LIST Result, Defs;
+  DEF  Def;
+  
+  Result = list_Nil();
+  for (Defs=prfs_Definitions(Search); !list_Empty(Defs); Defs=list_Cdr(Defs)) {
+    Def = (DEF)list_Car(Defs);
+    Result = list_Nconc(def_ApplyDefToClauseOnce(Def, Clause, Flags, Precedence),
+			Result);
+  }
+  return Result;
+}
+
+
+/**************************************************************
+  block with hyperresolution code starts here
+***************************************************************/
+
+typedef struct {
+  LITERAL NucleusLit;
+  LITERAL ElectronLit;
+  SUBST   ElectronSubst;
+} INF_MAPNODE, *INF_MAPITEM;
+
+
+static void inf_CopyHyperElectron(CLAUSE Clause, SUBST Subst2, SUBST Subst1,
+				  int PLitInd, LIST* Constraint,
+				  LIST* Succedent)
+/**************************************************************
+  INPUT:   An electron clause, a substitution, an index of a
+           succedent literal in this clause (the matched one),
+	   and two lists by reference.
+  RETURNS: Nothing.
+  EFFECTS: The constraint and succedent literals are copied into
+           the corresponding lists except for the literal with
+	   the given index. The composition <Subst2> ° <Subst1>
+	   is applied to all copied literals.
+	   The antecedent of the electron clause is empty, so
+	   there's no need for a third list by reference.
+***************************************************************/
+{
+  TERM Atom;
+  int  n, lc, j;
+
+#ifdef CHECK
+  if (clause_NumOfAnteLits(Clause) != 0) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_CopyHyperElectron: Electron contains antecedent literals.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  n  = clause_LastSuccedentLitIndex(Clause);
+  lc = clause_LastConstraintLitIndex(Clause);
+
+  for (j = clause_FirstConstraintLitIndex(Clause); j <= n; j++) {
+    if (j != PLitInd) {
+      Atom = subst_Apply(Subst1, term_Copy(clause_GetLiteralAtom(Clause, j)));
+      Atom = subst_Apply(Subst2, Atom);
+      if (j <= lc) 
+	*Constraint = list_Cons(Atom, *Constraint);
+      else /* Literal must be from succedent */
+	*Succedent  = list_Cons(Atom, *Succedent);
+    }
+  }
+}
+
+
+static CLAUSE inf_BuildHyperResolvent(CLAUSE Nucleus, SUBST Subst,
+				      LIST FoundMap, BOOL StrictlyMaximal,
+				      FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause <Nucleus> with solved sort constraint,
+	   the substitution <Subst> for <Nucleus>, a mapping
+	   <FoundMap> of literals of already found partner
+	   clauses, a boolean flag indicating whether this is
+	   a ordered or a standard hyper resolution inference
+	   a flag store and a precedence.
+  RETURNS: The newly created hyper resolvent.
+***************************************************************/
+{
+  CLAUSE  NewClause;
+  LIST    Constraint, Succedent, Parents, ParentNum, ParentLits, Scan;
+  int     i, bound, Depth;
+  LITERAL Lit;
+  SUBST   ESubst;
+  INF_MAPITEM MapItem;
+
+  Parents    = list_List(Nucleus);      /* parent clauses  */
+  ParentNum  = list_Nil();              /* parent clause numbers */
+  ParentLits = list_Nil();              /* literal indices */
+  Constraint = Succedent = list_Nil();  /* literals of the new clause */
+  
+  /* Get constraint literals from nucleus */
+  bound = clause_LastConstraintLitIndex(Nucleus);
+  for (i = clause_FirstConstraintLitIndex(Nucleus); i <= bound; i++)
+    Constraint =
+      list_Cons(subst_Apply(Subst,term_Copy(clause_GetLiteralAtom(Nucleus,i))),
+		Constraint);
+  /* Get succedent literals from nucleus */
+  bound = clause_LastSuccedentLitIndex(Nucleus);
+  for (i = clause_FirstSuccedentLitIndex(Nucleus); i <= bound; i++)
+    Succedent =
+      list_Cons(subst_Apply(Subst,term_Copy(clause_GetLiteralAtom(Nucleus,i))),
+		Succedent);
+
+  /* Now get the remaining data for the resolvent */
+  Depth = clause_Depth(Nucleus);
+  bound = clause_LastAntecedentLitIndex(Nucleus);
+  for (i = clause_FirstAntecedentLitIndex(Nucleus); i <= bound; i++) {
+    /* Search <FoundMap> for the nucleus literal with index <i> */
+    Lit = clause_GetLiteral(Nucleus, i);
+    for (Scan = FoundMap, MapItem = NULL; !list_Empty(Scan);
+	 Scan = list_Cdr(Scan)) {
+      MapItem = list_Car(Scan);
+      if (MapItem->NucleusLit == Lit)
+	break;
+    }
+
+    if (MapItem == NULL || MapItem->NucleusLit != Lit) {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In inf_BuildHyperResolvent: Map entry not found.");
+      misc_FinishErrorReport();
+    }
+
+    Lit       = MapItem->ElectronLit;
+    NewClause = clause_LiteralOwningClause(Lit);
+    ESubst    = MapItem->ElectronSubst;
+
+    Depth      = misc_Max(Depth, clause_Depth(NewClause));
+    Parents    = list_Cons(NewClause, Parents);
+    ParentNum  = list_Cons((POINTER) clause_Number(Nucleus), ParentNum);
+    ParentLits = list_Cons((POINTER) i, ParentLits);
+    ParentNum  = list_Cons((POINTER) clause_Number(NewClause), ParentNum);
+    ParentLits = list_Cons((POINTER) clause_LiteralGetIndex(Lit), ParentLits);
+
+    /* Get the remaining constraint and succedent literals from electron */
+    inf_CopyHyperElectron(NewClause,Subst,ESubst,clause_LiteralGetIndex(Lit),
+			  &Constraint, &Succedent);
+  }
+
+  /* create new clause and set clause data */
+  NewClause = clause_Create(Constraint, list_Nil(), Succedent, Flags,Precedence);
+
+  if (StrictlyMaximal)
+    clause_SetFromOrderedHyperResolution(NewClause);
+  else
+    clause_SetFromSimpleHyperResolution(NewClause);
+
+  clause_SetDepth(NewClause, Depth + 1);
+
+  clause_SetSplitDataFromList(NewClause, Parents);
+
+  clause_SetParentClauses(NewClause, list_NReverse(ParentNum));
+  clause_SetParentLiterals(NewClause, list_NReverse(ParentLits));
+
+  /* clean up */
+  list_Delete(Parents);
+  list_Delete(Constraint);
+  list_Delete(Succedent);
+
+  return NewClause;
+}
+
+
+static LIST inf_GetHyperResolutionPartnerLits(TERM Atom, SHARED_INDEX Index,
+					      BOOL StrictlyMaximal)
+/**************************************************************
+  INPUT:   An atom, a clause index, and a boolean flag.
+  RETURNS: A list of literals from purely positive clauses
+           from the index where either <StrictlyMaximal> is
+	   false or the literals are strictly maximal in their
+	   respective clauses.
+***************************************************************/
+{
+  LIST    Result, TermList, LitScan;
+  LITERAL NextLit;
+  CLAUSE  Clause;
+
+#ifdef CHECK  
+  if (!term_IsAtom(Atom)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_GetHyperResolutionPartnerLits: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Result   = list_Nil();
+  TermList = st_GetUnifier(cont_LeftContext(), sharing_Index(Index),
+			   cont_RightContext(), Atom);
+  
+  for (; !list_Empty(TermList); TermList = list_Pop(TermList)) {
+    if (!term_IsVariable(list_Car(TermList))) {
+      for (LitScan = sharing_NAtomDataList(list_Car(TermList)); 
+	   !list_Empty(LitScan); 
+	   LitScan = list_Cdr(LitScan)) {
+	NextLit = list_Car(LitScan);
+	Clause  = clause_LiteralOwningClause(NextLit);
+	if (clause_LiteralIsFromSuccedent(NextLit) &&
+	    (!StrictlyMaximal || clause_LiteralGetFlag(NextLit, STRICTMAXIMAL)) &&
+	    clause_HasSolvedConstraint(Clause) &&
+	    clause_HasEmptyAntecedent(Clause)) 
+	  Result = list_Cons(NextLit, Result);
+      }
+    }
+  }
+  return Result;
+}
+
+static LIST inf_HyperResolvents(CLAUSE Clause, SUBST Subst, LIST Restlits,
+				int GlobalMaxVar, LIST FoundMap, 
+				BOOL StrictlyMaximal, SHARED_INDEX Index,
+				FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A nucleus <Clause> where the sort constraint is
+           solved,
+           a substitution, that has to be applied to the
+	   nucleus,
+	   a list <Restlits> of antecedent literals for which
+	   a partner clause is searched,
+	   a list <FoundMap> of map items (n,e,s), where
+	   n is an antecedent literal from the nucleus,
+	   e is a positive literal from an electron clause,
+	   that is unifiable with n and s is a substitution
+	   that has to be applied to the electron clause,
+	   a flag store and
+	   a precedence.
+	   A main invariant of our algorithm is that all involved
+	   clauses are pairwise variable disjoint. For that reason
+	   we need, when building the resolvent, only apply the electron
+	   specific substitution and the composed substitution <Subst>
+	   to the electron clauses, and only <Subst> to the nucleus clause.
+  RETURNS: The list of hyper-resolvents.
+***************************************************************/
+{
+  LITERAL Lit, PLit;
+
+  if (list_Empty(Restlits)) {
+    /* This case stops the recursion */
+    LIST        Scan;
+    INF_MAPITEM MapItem;
+
+    /* A posteriori test for the electron literals */
+    if (StrictlyMaximal) { /* only for ordered hyper resolution */
+      for (Scan = FoundMap; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+	MapItem = list_Car(Scan);
+	Lit = MapItem->ElectronLit;
+	if (!inf_LitMaxWith2Subst(clause_LiteralOwningClause(Lit),
+				  clause_LiteralGetIndex(Lit), -1, Subst,
+				  MapItem->ElectronSubst,TRUE,Flags,Precedence))
+	  return list_Nil();
+      }
+    }
+    /* Build the resolvent */
+    return list_List(inf_BuildHyperResolvent(Clause, Subst, FoundMap,
+					     StrictlyMaximal,Flags,Precedence));
+  }
+  else {
+    CLAUSE      PartnerCopy;
+    LIST        Result, NextLits;
+    TERM        AtomCopy;
+    SUBST       NewSubst, RightSubst, HelpSubst;
+    SYMBOL      NewMaxVar;
+    int         PLitInd;
+    BOOL        Swapped;
+    INF_MAPNODE MapNode;
+
+    Result   = list_Nil();
+    Restlits = clause_MoveBestLiteralToFront(list_Copy(Restlits), Subst,
+					     GlobalMaxVar,
+					     clause_HyperLiteralIsBetter);
+    Lit      = list_Car(Restlits);
+    Restlits = list_Pop(Restlits);
+    AtomCopy = subst_Apply(Subst, term_Copy(clause_LiteralAtom(Lit)));
+
+    Swapped = FALSE;
+    
+    /* The 'endless' loop may run twice for equations, once for other atoms */
+    while (TRUE) {
+      NextLits = inf_GetHyperResolutionPartnerLits(AtomCopy,Index,
+						   StrictlyMaximal);
+      
+      for ( ; !list_Empty(NextLits); NextLits = list_Pop(NextLits)) {
+	
+	PLit        = list_Car(NextLits);
+	PLitInd     = clause_LiteralGetIndex(PLit);
+	PartnerCopy = clause_Copy(clause_LiteralOwningClause(PLit));
+	
+	clause_RenameVarsBiggerThan(PartnerCopy, GlobalMaxVar);
+	PLit        = clause_GetLiteral(PartnerCopy, PLitInd);
+	
+	NewMaxVar   = term_MaxVar(clause_LiteralAtom(PLit));
+	NewMaxVar   = symbol_GreaterVariable(GlobalMaxVar, NewMaxVar) ?
+	  GlobalMaxVar : NewMaxVar;
+	
+	cont_Check();
+	if (!unify_UnifyNoOC(cont_LeftContext(), AtomCopy, cont_RightContext(),
+			     clause_LiteralAtom(PLit))) {
+	  misc_StartErrorReport();
+	  misc_ErrorReport("\n In inf_HyperResolvents: Unification failed.");
+	  misc_FinishErrorReport();
+	}
+	subst_ExtractUnifier(cont_LeftContext(), &NewSubst,
+			     cont_RightContext(), &RightSubst);
+	cont_Reset();
+	
+	HelpSubst = NewSubst;
+	NewSubst  = subst_Compose(NewSubst, subst_Copy(Subst));
+	subst_Delete(HelpSubst);
+	
+	MapNode.NucleusLit    = Lit;
+	MapNode.ElectronLit   = PLit;
+	MapNode.ElectronSubst = RightSubst;
+	FoundMap = list_Cons(&MapNode, FoundMap);
+	
+	Result = list_Nconc(inf_HyperResolvents(Clause, NewSubst, Restlits,
+						NewMaxVar, FoundMap,
+						StrictlyMaximal, Index, Flags,
+						Precedence),
+			    Result);
+	
+	subst_Delete(NewSubst);
+	subst_Delete(RightSubst);
+	clause_Delete(PartnerCopy);
+	FoundMap = list_Pop(FoundMap);
+      }
+      if (!Swapped && fol_IsEquality(AtomCopy)) {
+	term_EqualitySwap(AtomCopy);
+	Swapped = TRUE;
+      } else
+	break;
+    } /* end of 'endless' loop */
+
+    list_Delete(Restlits);
+    term_Delete(AtomCopy);
+
+    return Result;
+  }
+}
+
+
+static LIST inf_GetAntecedentLiterals(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A clause 
+  RETURNS: The list of all antecedent literals of the clause.
+***************************************************************/
+{ 
+  int  lc, i;
+  LIST Result;
+  
+  Result = list_Nil();
+  lc     = clause_LastAntecedentLitIndex(Clause);
+  for (i = clause_FirstAntecedentLitIndex(Clause); i <= lc ; i++) {
+    Result = list_Cons(clause_GetLiteral(Clause, i), Result);
+  }
+  return Result;
+}
+
+
+static LIST inf_ForwardHyperResolution(CLAUSE GivenClause, SHARED_INDEX Index,
+				       BOOL StrictlyMaximal, FLAGSTORE Flags,
+				       PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause with an solved sort constraint, an 'Index'
+           of clauses, a boolean flag, a flag store and a
+	   precedence.
+  RETURNS: A list of clauses inferred from  <GivenClause> by
+           hyper resolution wrt. the index. 
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{
+  LIST Result, RestLits;
+;
+
+#ifdef CHECK
+  if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_ForwardHyperResolution: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  if (clause_HasEmptyAntecedent(GivenClause))
+    return list_Nil();
+
+  Result = list_Nil();
+  
+  /* Build up list of all antecedent literals. */
+  RestLits = inf_GetAntecedentLiterals(GivenClause);
+  
+  Result =  list_Nconc(inf_HyperResolvents(GivenClause, subst_Nil(),
+					   RestLits,clause_MaxVar(GivenClause),
+					   list_Nil(),StrictlyMaximal,Index,
+					   Flags, Precedence), 
+		       Result);
+  list_Delete(RestLits);
+
+  return Result;
+}
+
+
+static LIST inf_BackwardHyperResolution(CLAUSE Electron, SHARED_INDEX Index,
+					BOOL StrictlyMaximal, FLAGSTORE Flags,
+					PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause with an solved sort constraint,
+           an 'Index' of clauses, a boolean flag, a flag store,
+	   and a precedence.
+  RETURNS: A list of clauses inferred by hyper resolution 
+           wrt. the index with <Electron> as an electron.
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{
+  CLAUSE ElectronCopy;
+  LIST   Result;
+  int    i, ls;
+
+  if (!clause_HasEmptyAntecedent(Electron) ||
+      clause_HasEmptySuccedent(Electron))
+    return list_Nil();
+
+  Result = list_Nil();
+
+  ElectronCopy = clause_Copy(Electron);
+
+  /* Search succedent literal in <Electron> */
+  ls = clause_LastSuccedentLitIndex(ElectronCopy);
+  for (i = clause_FirstSuccedentLitIndex(Electron); i <= ls; i++) {
+    LITERAL ElecLit;
+    TERM    ElecAtom;
+
+    ElecLit  = clause_GetLiteral(ElectronCopy, i);
+    ElecAtom = clause_LiteralAtom(ElecLit);
+
+    if (!StrictlyMaximal || clause_LiteralGetFlag(ElecLit, STRICTMAXIMAL)) {
+      LIST CandAtoms;
+      BOOL Swapped;
+
+      Swapped = FALSE;
+
+      /* The 'endless' loop may run twice for equations, once for other atoms */
+      while (TRUE) {
+	/* Get unifiable antecedent literals in nucleus */
+	CandAtoms = st_GetUnifier(cont_LeftContext(), sharing_Index(Index),
+				  cont_RightContext(), ElecAtom);
+	
+	for ( ; !list_Empty(CandAtoms); CandAtoms = list_Pop(CandAtoms)) {
+	  if (!term_IsVariable(list_Car(CandAtoms))) {
+	    LIST CandLits;
+	    
+	    CandLits = sharing_NAtomDataList(list_Car(CandAtoms));
+	    
+	    for (; !list_Empty(CandLits); CandLits = list_Cdr(CandLits)) {
+	      LITERAL   NucLit;
+	      TERM      NucAtom;
+	      CLAUSE    Nucleus;
+	      
+	      NucLit    = list_Car(CandLits);
+	      NucAtom   = clause_LiteralAtom(NucLit);
+	      Nucleus   = clause_LiteralOwningClause(NucLit);
+	      
+	      if (clause_LiteralIsFromAntecedent(NucLit) &&
+		  clause_HasSolvedConstraint(Nucleus)) {
+		LIST    FoundMap, RestLits;
+		SUBST   LeftSubst, RightSubst;
+		SYMBOL  GlobalMaxVar, MaxVar;
+		INF_MAPNODE MapNode;
+		
+		GlobalMaxVar = clause_MaxVar(Nucleus);
+		clause_RenameVarsBiggerThan(ElectronCopy, GlobalMaxVar);
+		MaxVar       = clause_SearchMaxVar(ElectronCopy);
+		GlobalMaxVar = symbol_GreaterVariable(GlobalMaxVar, MaxVar) ?
+		  GlobalMaxVar : MaxVar;
+		/* Now ElecLit is renamed, too */
+
+		RestLits     = inf_GetAntecedentLiterals(Nucleus);
+		RestLits     = list_PointerDeleteElement(RestLits, NucLit);
+
+		/* Get unifier */
+		cont_Check();
+		if (!unify_UnifyNoOC(cont_LeftContext(), NucAtom,
+				     cont_RightContext(), ElecAtom)) {
+		  misc_StartErrorReport();
+		  misc_ErrorReport("\n In inf_BackwardHyperResolution: Unification failed.");
+		  misc_FinishErrorReport();
+		}
+		subst_ExtractUnifier(cont_LeftContext(), &LeftSubst,
+				     cont_RightContext(), &RightSubst);
+		cont_Reset();
+		
+		MapNode.NucleusLit    = NucLit;
+		MapNode.ElectronLit   = ElecLit;
+		MapNode.ElectronSubst = RightSubst;
+		FoundMap = list_List(&MapNode);
+		
+		Result = list_Nconc(inf_HyperResolvents(Nucleus, LeftSubst,
+							RestLits, GlobalMaxVar,
+							FoundMap,StrictlyMaximal,
+							Index, Flags,Precedence),
+				    Result);
+		
+		/* clean up */
+		subst_Delete(LeftSubst);
+		subst_Delete(RightSubst);
+		list_Delete(RestLits);
+		list_Free(FoundMap);	    
+	      } /* if a nucleus has been found */
+	    } /* for all nucleus candidate literals */
+	  } /* if term is atom */
+	} /* for all nucleus candidate atoms */
+      	if (!Swapped && fol_IsEquality(ElecAtom)) {
+	  term_EqualitySwap(ElecAtom);    /* Atom is from copied clause */
+	  Swapped = TRUE;
+	} else
+	  break;
+      } /* end of 'endless' loop */
+    } /* for all lits usable in electron for hyper resolution */
+  } /* for all lits in succedent */
+  clause_Delete(ElectronCopy);
+    
+  return Result;
+}
+
+
+LIST inf_GeneralHyperResolution(CLAUSE GivenClause, SHARED_INDEX Index,
+				BOOL Ordered, FLAGSTORE Flags,
+				PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, an 'Index' of clauses, a boolean flag,
+           a flag store and a precedence.
+  RETURNS: A list of clauses inferred by
+           (ordered) hyper resolution wrt. the index.
+	   If <Ordered>=TRUE then ordered hyper resolution
+	   inferences are made, else standard hyper resolution
+	   inferences.
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{ 
+  LIST Result;
+
+  Result = list_Nil();
+  if (clause_HasSolvedConstraint(GivenClause)) {
+    Result = inf_ForwardHyperResolution(GivenClause, Index, Ordered,
+					Flags, Precedence); 
+    Result = list_Nconc(inf_BackwardHyperResolution(GivenClause, Index, Ordered,
+						    Flags, Precedence),
+			Result); 
+  }
+  return Result;
+} 
+
+
+LIST inf_DerivableClauses(PROOFSEARCH Search, CLAUSE GivenClause)
+/**************************************************************
+  INPUT:   A clause and an Index, usually the WorkedOffIndex.
+  RETURNS: A list of clauses derivable from 'GivenClause' wrt index.
+  EFFECT:  Allocates memory for the clauselistnodes and new clauses.
+***************************************************************/
+{
+  LIST         ListOfDerivedClauses;
+  SHARED_INDEX ShIndex;
+  SORTTHEORY   Dynamic;
+  FLAGSTORE    Flags;
+  PRECEDENCE   Precedence;
+
+  Flags        = prfs_Store(Search);
+  Precedence   = prfs_Precedence(Search);
+
+#ifdef CHECK
+  if (!clause_IsClause(GivenClause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_DerivableClauses: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  ListOfDerivedClauses = list_Nil();
+  ShIndex              = prfs_WorkedOffSharingIndex(Search);
+  Dynamic              = prfs_DynamicSortTheory(Search);
+
+  if (Dynamic && !clause_HasSolvedConstraint(GivenClause)) {
+
+    if (clause_HasTermSortConstraintLits(GivenClause)) {
+      if (flag_GetFlagValue(Flags, flag_ISOR))
+	ListOfDerivedClauses =
+	  list_Nconc(inf_ForwardSortResolution(GivenClause,
+					       sort_TheoryIndex(Dynamic),
+					       Dynamic, FALSE, Flags,Precedence),
+		     ListOfDerivedClauses);
+    }
+    else
+      if (flag_GetFlagValue(Flags, flag_IEMS))	
+	ListOfDerivedClauses =
+	  list_Nconc(inf_ForwardEmptySort(GivenClause,
+					  sort_TheoryIndex(Dynamic), Dynamic,
+					  FALSE, Flags, Precedence), 
+		     ListOfDerivedClauses); 
+  } else { /* Given with solved Constraint! */
+
+    if (Dynamic && flag_GetFlagValue(Flags, flag_IEMS))
+      ListOfDerivedClauses =
+	list_Nconc(inf_BackwardEmptySort(GivenClause, sharing_Index(ShIndex),
+					 Dynamic, FALSE, Flags, Precedence),
+		   ListOfDerivedClauses); 
+
+    if (Dynamic && flag_GetFlagValue(Flags, flag_ISOR))
+      ListOfDerivedClauses =
+	list_Nconc(inf_BackwardSortResolution(GivenClause,
+					      sharing_Index(ShIndex), Dynamic,
+					      FALSE, Flags, Precedence),
+		   ListOfDerivedClauses);
+
+    if (flag_GetFlagValue(Flags, flag_IEQR))
+      ListOfDerivedClauses =
+	list_Nconc(inf_EqualityResolution(GivenClause, TRUE, Flags, Precedence),
+		   ListOfDerivedClauses);
+
+    if (flag_GetFlagValue(Flags, flag_IERR))
+      ListOfDerivedClauses =
+	list_Nconc(inf_EqualityResolution(GivenClause, FALSE, Flags, Precedence),
+		   ListOfDerivedClauses);
+
+    if (flag_GetFlagValue(Flags, flag_IMPM))
+      ListOfDerivedClauses =
+	list_Nconc(inf_MergingParamodulation(GivenClause, ShIndex, Flags,
+					     Precedence),
+		   ListOfDerivedClauses);
+
+    if (flag_GetFlagValue(Flags, flag_IEQF))
+      ListOfDerivedClauses =
+	list_Nconc(inf_EqualityFactoring(GivenClause,Flags, Precedence),
+		   ListOfDerivedClauses);
+
+    switch (flag_GetFlagValue(Flags, flag_IOFC)) {
+    case flag_FACTORINGOFF:
+      break; /* Do nothing */
+    case flag_FACTORINGONLYRIGHT:
+      ListOfDerivedClauses =
+	list_Nconc(inf_GeneralFactoring(GivenClause, TRUE, FALSE,TRUE, Flags,
+					Precedence),
+		   ListOfDerivedClauses);
+      break;
+    case flag_FACTORINGRIGHTANDLEFT:
+      ListOfDerivedClauses =
+	list_Nconc(inf_GeneralFactoring(GivenClause, TRUE, TRUE, TRUE, Flags,
+					Precedence),
+		   ListOfDerivedClauses);
+      break;
+    default:
+      misc_StartUserErrorReport();
+      misc_UserErrorReport("\n Error: Flag \"IOFC\" has invalid value.\n");
+      misc_FinishUserErrorReport();
+    }
+
+    if (flag_GetFlagValue(Flags, flag_ISFC))
+      ListOfDerivedClauses =
+	list_Nconc(inf_GeneralFactoring(GivenClause, FALSE, TRUE, TRUE, Flags,
+					Precedence),
+		   ListOfDerivedClauses);
+
+    if (flag_GetFlagValue(Flags, flag_ISPR))
+      ListOfDerivedClauses =
+	list_Nconc(inf_SuperpositionRight(GivenClause,ShIndex,Flags,Precedence),
+		   ListOfDerivedClauses);
+
+    if (flag_GetFlagValue(Flags, flag_ISPM))
+      ListOfDerivedClauses =
+	list_Nconc(inf_Paramodulation(GivenClause, ShIndex, Flags, Precedence),
+		   ListOfDerivedClauses);
+
+    if (flag_GetFlagValue(Flags, flag_IOPM))
+      ListOfDerivedClauses =
+	list_Nconc(inf_OrderedParamodulation(GivenClause, ShIndex, Flags,
+					     Precedence),
+		   ListOfDerivedClauses);  
+
+    if (flag_GetFlagValue(Flags, flag_ISPL)) 
+      ListOfDerivedClauses =
+	list_Nconc(inf_SuperpositionLeft(GivenClause, ShIndex, Flags,Precedence),
+		   ListOfDerivedClauses);  
+
+    switch (flag_GetFlagValue(Flags, flag_IORE)) {
+    case flag_ORDEREDRESOLUTIONOFF:
+      break;   /* Do nothing */
+    case flag_ORDEREDRESOLUTIONNOEQUATIONS:  /* no equations */
+      ListOfDerivedClauses =
+	list_Nconc(inf_GeneralResolution(GivenClause,ShIndex,TRUE,FALSE,Flags,
+					 Precedence),
+		   ListOfDerivedClauses);
+      break;
+
+    case flag_ORDEREDRESOLUTIONWITHEQUATIONS:  /* allow equations */
+      ListOfDerivedClauses =
+	list_Nconc(inf_GeneralResolution(GivenClause,ShIndex,TRUE,TRUE, Flags,
+					 Precedence),
+		   ListOfDerivedClauses);
+      break;
+    default:
+      misc_StartUserErrorReport();
+      misc_UserErrorReport("\n Error: Flag \"IORE\" has invalid value.\n");
+      misc_FinishUserErrorReport();
+    }
+      
+
+    switch (flag_GetFlagValue(Flags, flag_ISRE)) {
+    case flag_STANDARDRESOLUTIONOFF:
+      break;   /* Do nothing */
+    case flag_STANDARDRESOLUTIONNOEQUATIONS:  /* no equations */
+      ListOfDerivedClauses =
+	list_Nconc(inf_GeneralResolution(GivenClause,ShIndex,FALSE,FALSE,Flags,
+ Precedence),
+		   ListOfDerivedClauses);
+      break;
+    case flag_STANDARDRESOLUTIONWITHEQUATIONS:  /* allow equations */
+      ListOfDerivedClauses =
+	list_Nconc(inf_GeneralResolution(GivenClause,ShIndex,FALSE,TRUE,Flags,
+					 Precedence),
+		   ListOfDerivedClauses);
+      break;
+    default:
+      misc_StartUserErrorReport();
+      misc_UserErrorReport("\n Error: Flag \"ISRE\" has invalid value.\n");
+      misc_FinishUserErrorReport();
+    }
+
+    if (flag_GetFlagValue(Flags, flag_IUNR))
+      ListOfDerivedClauses =
+	list_Nconc(inf_UnitResolution(GivenClause, ShIndex, FALSE,
+				      Flags, Precedence),
+		   ListOfDerivedClauses);
+
+    if (flag_GetFlagValue(Flags, flag_IBUR))
+      ListOfDerivedClauses =
+	list_Nconc(inf_BoundedDepthUnitResolution(GivenClause,ShIndex,FALSE,
+						  Flags, Precedence),
+		   ListOfDerivedClauses);
+
+    if (flag_GetFlagValue(Flags, flag_ISHY))
+      ListOfDerivedClauses =
+      	list_Nconc(inf_GeneralHyperResolution(GivenClause,ShIndex,FALSE,Flags,
+					      Precedence),
+		   ListOfDerivedClauses);
+
+    if (flag_GetFlagValue(Flags, flag_IOHY))
+      ListOfDerivedClauses =
+      	list_Nconc(inf_GeneralHyperResolution(GivenClause,ShIndex,TRUE,Flags,
+					      Precedence),
+		   ListOfDerivedClauses);
+
+    if (flag_GetFlagValue(Flags, flag_IURR))
+      ListOfDerivedClauses =
+	list_Nconc(inf_URResolution(GivenClause, ShIndex, Flags, Precedence),
+		   ListOfDerivedClauses);
+
+    if (flag_GetFlagValue(Flags, flag_IDEF))
+      ListOfDerivedClauses =
+	list_Nconc(inf_ApplyDefinition(Search, GivenClause, Flags, Precedence),
+		   ListOfDerivedClauses);
+  }
+
+  return ListOfDerivedClauses;
+}
diff --git a/test/spass/rules-inf.h b/test/spass/rules-inf.h
new file mode 100644
index 0000000000000000000000000000000000000000..d900bc5d6d06237a7c4d4db59fbd50f16aeea0de
--- /dev/null
+++ b/test/spass/rules-inf.h
@@ -0,0 +1,165 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                INFERENCE RULES                         * */
+/* *                                                        * */
+/* *  $Module:   INFRULES                                   * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _INFRULES_
+#define _INFRULES_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "search.h"
+#include "rules-split.h"
+#include "rules-sort.h"
+#include "rules-ur.h"
+#include "subst.h"
+#include "unify.h"
+#include "st.h"
+#include "defs.h"
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/        
+
+LIST inf_DerivableClauses(PROOFSEARCH, CLAUSE);
+
+LIST inf_EqualityResolution(CLAUSE, BOOL, FLAGSTORE, PRECEDENCE);
+LIST inf_EqualityFactoring(CLAUSE, FLAGSTORE, PRECEDENCE);
+
+LIST inf_MergingParamodulation(CLAUSE, SHARED_INDEX, FLAGSTORE, PRECEDENCE);
+
+LIST inf_GenSuperpositionLeft(CLAUSE,SHARED_INDEX,BOOL,BOOL,BOOL,FLAGSTORE, PRECEDENCE);
+LIST inf_GenSuperpositionRight(CLAUSE,SHARED_INDEX,BOOL,BOOL,BOOL,FLAGSTORE, PRECEDENCE);
+
+LIST inf_BoundedDepthUnitResolution(CLAUSE, SHARED_INDEX, BOOL, FLAGSTORE, PRECEDENCE);
+LIST inf_UnitResolution(CLAUSE, SHARED_INDEX, BOOL, FLAGSTORE, PRECEDENCE);
+LIST inf_GeneralResolution(CLAUSE, SHARED_INDEX, BOOL, BOOL, FLAGSTORE, PRECEDENCE);
+
+BOOL inf_HyperLiteralIsBetter(LITERAL, NAT, LITERAL, NAT);
+LIST inf_GeneralHyperResolution(CLAUSE, SHARED_INDEX, BOOL, FLAGSTORE, PRECEDENCE);
+
+LIST inf_GeneralFactoring(CLAUSE, BOOL, BOOL, BOOL, FLAGSTORE, PRECEDENCE);
+
+LIST inf_ApplyDefinition(PROOFSEARCH, CLAUSE, FLAGSTORE, PRECEDENCE);
+
+/**************************************************************/
+/* Inline Functions                                           */
+/**************************************************************/        
+
+static __inline__ LIST inf_Paramodulation(CLAUSE GivenClause,
+					  SHARED_INDEX ShIndex,
+					  FLAGSTORE Flags,
+					  PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, an Index, usually the WorkedOffIndex, a 
+           flag store and a precedence.
+  RETURNS: A list of clauses derivable from the GivenClause by 
+           paramodulation wrt. the Index. 
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{ 
+  return list_Nconc(inf_GenSuperpositionLeft(GivenClause, ShIndex, FALSE,
+					     FALSE, FALSE, Flags, Precedence),
+		    inf_GenSuperpositionRight(GivenClause, ShIndex, FALSE,
+					      FALSE, FALSE, Flags, Precedence));
+}
+
+static __inline__ LIST inf_OrderedParamodulation(CLAUSE GivenClause,
+						 SHARED_INDEX ShIndex,
+						 FLAGSTORE Flags,
+						 PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, an Index, usually the WorkedOffIndex, a 
+           flag store and a precedence.
+  RETURNS: A list of clauses derivable from the Givenclause by 
+           ordered paramodulation wrt. the Index. 
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{
+  return list_Nconc(inf_GenSuperpositionLeft(GivenClause, ShIndex, TRUE,
+					     FALSE, FALSE, Flags, Precedence),
+		    inf_GenSuperpositionRight(GivenClause, ShIndex, TRUE,
+					      FALSE, FALSE, Flags, Precedence));
+}
+
+static __inline__ LIST inf_SuperpositionLeft(CLAUSE GivenClause,
+					     SHARED_INDEX ShIndex,
+					     FLAGSTORE Flags,
+					     PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, an Index, usually the WorkedOffIndex, a
+           flag store, and a precedence.
+  RETURNS: A list of clauses derivable from the Givenclause by 
+           superposition left wrt. the Index. 
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{
+  return inf_GenSuperpositionLeft(GivenClause,ShIndex,TRUE,TRUE,FALSE,Flags, Precedence);
+}
+
+static __inline__ LIST inf_SuperpositionRight(CLAUSE GivenClause,
+					      SHARED_INDEX ShIndex,
+					      FLAGSTORE Flags,
+					      PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, an Index, usually the WorkedOffIndex, a 
+           flag store and a precedence.
+  RETURNS: A list of clauses derivable from the Givenclause by 
+           superposition right wrt. the Index. 
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{
+  return inf_GenSuperpositionRight(GivenClause,ShIndex,TRUE,TRUE,FALSE,Flags, Precedence);
+}
+
+
+#endif
+
diff --git a/test/spass/rules-red.c b/test/spass/rules-red.c
new file mode 100644
index 0000000000000000000000000000000000000000..609b3cf9c18ed3ca144e4c4d223bd3d883792f48
--- /dev/null
+++ b/test/spass/rules-red.c
@@ -0,0 +1,4508 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                REDUCTION RULES                         * */
+/* *                                                        * */
+/* *  $Module:   REDRULES                                   * */
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                       * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "rules-red.h"
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  Globals                                               * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* Needed for term stamping in red_RewriteRedUnitClause */
+static NAT red_STAMPID;
+ 
+const NAT red_USABLE    = 1;
+const NAT red_WORKEDOFF = 2;
+const NAT red_ALL       = 3;
+
+
+/**************************************************************/
+/* FUNTION PROTOTYPES                                         */
+/**************************************************************/
+
+static BOOL red_SortSimplification(SORTTHEORY, CLAUSE, NAT, BOOL, FLAGSTORE,
+				   PRECEDENCE, CLAUSE*);
+static BOOL red_SelectedStaticReductions(PROOFSEARCH, CLAUSE*, CLAUSE*, LIST*,
+					 NAT);
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  Functions                                             * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+
+static void red_HandleRedundantIndexedClauses(PROOFSEARCH Search, LIST Blocked,
+					      CLAUSE RedClause)
+/*********************************************************
+  INPUT:   A proof search object, a list <Blocked> of clauses from
+           the proof search object and a clause that causes the
+	   already indexed clauses in <Blocked> to be redundant.
+  RETURNS: Nothing.
+**********************************************************/
+{
+  FLAGSTORE Flags;
+  CLAUSE    Clause;
+  LIST      Scan;
+
+  Flags = prfs_Store(Search);
+  for (Scan = Blocked; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    Clause = (CLAUSE)list_Car(Scan);
+    if (prfs_SplitLevelCondition(clause_SplitLevel(RedClause),clause_SplitLevel(Clause),
+				 prfs_LastBacktrackLevel(Search)))
+      split_DeleteClauseAtLevel(Search, Clause, clause_SplitLevel(RedClause));
+    else {
+      if (clause_GetFlag(Clause, WORKEDOFF)) {
+	if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+	  prfs_MoveWorkedOffDocProof(Search, Clause);
+	else
+	  prfs_DeleteWorkedOff(Search, Clause);
+      }
+      else
+	if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+	  prfs_MoveUsableDocProof(Search, Clause);
+	else
+	  prfs_DeleteUsable(Search, Clause);
+    }
+  }
+}
+
+static void red_HandleRedundantDerivedClauses(PROOFSEARCH Search, LIST Blocked,
+					      CLAUSE RedClause)
+/*********************************************************
+  INPUT:   A proof search object, a list <Blocked> of clauses from
+           the proof search object and a clause that causes the
+	   derived clauses in <Blocked> to be redundant.
+  RETURNS: Nothing.
+**********************************************************/
+{
+  CLAUSE Clause;
+  LIST   Scan;
+
+  for (Scan = Blocked; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    Clause = (CLAUSE)list_Car(Scan);
+    if (prfs_SplitLevelCondition(clause_SplitLevel(RedClause),clause_SplitLevel(Clause),
+				 prfs_LastBacktrackLevel(Search))) {
+      split_KeepClauseAtLevel(Search, Clause, clause_SplitLevel(RedClause));
+    }
+    else {
+      if (flag_GetFlagValue(prfs_Store(Search), flag_DOCPROOF))
+	prfs_InsertDocProofClause(Search, Clause);
+      else
+	clause_Delete(Clause);
+    }
+  }
+}
+
+
+void red_Init(void)
+/*********************************************************
+  INPUT:   None.
+  RETURNS: Nothing.
+  EFFECT:  Initializes the Reduction module, in particular
+           its stampid to stamp terms.
+**********************************************************/
+{
+  red_STAMPID = term_GetStampID();
+}
+
+
+static void red_DocumentObviousReductions(CLAUSE Clause, LIST Indexes)
+/*********************************************************
+  INPUT:   A clause and a list of literal indexes removed by
+           obvious reductions.
+  RETURNS: None
+  MEMORY:  The <Indexes> list is consumed.
+**********************************************************/
+{
+  list_Delete(clause_ParentClauses(Clause));
+  list_Delete(clause_ParentLiterals(Clause));
+  clause_SetParentClauses(Clause, list_Nil());
+  clause_SetParentLiterals(Clause, Indexes);
+
+  clause_AddParentClause(Clause,clause_Number(Clause));  /* Has to be done before increasing it! */
+
+  clause_SetNumber(Clause, clause_IncreaseCounter());
+  clause_SetFromObviousReductions(Clause);
+}
+
+
+static BOOL red_ObviousReductions(CLAUSE Clause, BOOL Document,
+				  FLAGSTORE Flags, PRECEDENCE Precedence,
+				  CLAUSE *Changed)
+/**********************************************************
+  INPUT:   A clause, a boolean flag for proof
+           documentation, a flag store and a precedence.
+  RETURNS: TRUE iff  obvious reductions are possible.
+           If <Document>  is false the clause is
+	   destructively changed,
+	   else a reduced copy of  the clause is returned
+	   in <*Changed>.
+  EFFECT:  Multiple occurrences of the same literal as 
+           well as trivial equations are removed.
+********************************************************/
+{
+  int  i, j, end;
+  LIST Indexes;
+  TERM Atom, PartnerAtom;
+
+#ifdef CHECK
+  clause_Check(Clause, Flags, Precedence);
+#endif
+
+  Indexes = list_Nil();
+  end     = clause_LastAntecedentLitIndex(Clause);
+    
+  for (i = clause_FirstConstraintLitIndex(Clause); i <= end; i++) {
+    Atom = clause_LiteralAtom(clause_GetLiteral(Clause,i));
+    if (fol_IsEquality(Atom) &&
+	!clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause, i)) &&
+	term_Equal(term_FirstArgument(Atom),term_SecondArgument(Atom))) {
+      Indexes = list_Cons((POINTER)i,Indexes);
+    } 
+    else
+      for (j = i+1; j <= end; j++) {
+	PartnerAtom = clause_LiteralAtom(clause_GetLiteral(Clause,j));
+	if (term_Equal(PartnerAtom, Atom) ||
+	    (fol_IsEquality(Atom) &&
+	     fol_IsEquality(PartnerAtom) &&
+	     term_Equal(term_FirstArgument(Atom),term_SecondArgument(PartnerAtom)) &&
+	     term_Equal(term_FirstArgument(PartnerAtom),term_SecondArgument(Atom)))) {
+	  Indexes = list_Cons((POINTER)i,Indexes);
+	  j       = end;
+	}
+      }
+  }
+
+  end = clause_LastSuccedentLitIndex(Clause);
+    
+  for (i = clause_FirstSuccedentLitIndex(Clause); i <= end; i++) {
+    Atom = clause_LiteralAtom(clause_GetLiteral(Clause,i));
+    for (j = i+1; j <= end; j++) {
+      PartnerAtom = clause_LiteralAtom(clause_GetLiteral(Clause,j));
+      if (term_Equal(PartnerAtom,Atom) ||
+	  (fol_IsEquality(Atom) &&
+	   fol_IsEquality(PartnerAtom) &&
+	   term_Equal(term_FirstArgument(Atom),term_SecondArgument(PartnerAtom)) &&
+	   term_Equal(term_FirstArgument(PartnerAtom),term_SecondArgument(Atom)))) {
+	Indexes = list_Cons((POINTER)i,Indexes);
+	j       = end;
+      }
+    }
+  }
+
+  if (clause_Length(Clause) == 1 &&
+      clause_NumOfAnteLits(Clause) == 1 &&
+      !list_PointerMember(Indexes,(POINTER)clause_FirstAntecedentLitIndex(Clause)) &&
+      fol_IsEquality(clause_GetLiteralAtom(Clause,clause_FirstAntecedentLitIndex(Clause)))) {
+    cont_StartBinding();
+    if (unify_UnifyCom(cont_LeftContext(),
+		       term_FirstArgument(clause_LiteralAtom(clause_GetLiteral(Clause,clause_FirstAntecedentLitIndex(Clause)))),
+		       term_SecondArgument(clause_LiteralAtom(clause_GetLiteral(Clause,clause_FirstAntecedentLitIndex(Clause))))))
+      Indexes = list_Cons((POINTER)clause_FirstAntecedentLitIndex(Clause),Indexes);
+    cont_BackTrack();
+  }
+
+  if (!list_Empty(Indexes)) {
+    if (flag_GetFlagValue(Flags, flag_POBV)) {
+      fputs("\nObvious: ", stdout);
+      clause_Print(Clause);
+      fputs(" ==> ", stdout);
+    }      
+    if (Document) {
+      CLAUSE Copy;
+      Copy = clause_Copy(Clause);
+      clause_DeleteLiterals(Copy,Indexes, Flags, Precedence);
+      red_DocumentObviousReductions(Copy,Indexes); /* Indexes is consumed */
+      if (flag_GetFlagValue(Flags, flag_POBV))
+	clause_Print(Copy);
+      *Changed = Copy;
+    }
+    else {
+      clause_DeleteLiterals(Clause,Indexes, Flags, Precedence);
+      list_Delete(Indexes);
+      if (flag_GetFlagValue(Flags, flag_POBV))
+	clause_Print(Clause);
+    }
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+
+static void red_DocumentCondensing(CLAUSE Clause, LIST Indexes)
+/*********************************************************
+  INPUT:   A clause and a list of literal indexes removed by condensing.
+  RETURNS: Nothing.
+  MEMORY:  The <Indexes> list is consumed.
+**********************************************************/
+{
+  list_Delete(clause_ParentClauses(Clause));
+  list_Delete(clause_ParentLiterals(Clause));
+  clause_SetParentClauses(Clause, list_Nil());
+  clause_SetParentLiterals(Clause, Indexes);
+
+  clause_AddParentClause(Clause,clause_Number(Clause));  /* Has to be done before increasing it! */
+
+  clause_SetNumber(Clause, clause_IncreaseCounter());
+  clause_SetFromCondensing(Clause);
+}
+
+static BOOL red_Condensing(CLAUSE Clause, BOOL Document, FLAGSTORE Flags,
+			   PRECEDENCE Precedence, CLAUSE *Changed)
+/**********************************************************
+  INPUT:   A non-empty unshared clause, a boolean flag
+           concerning proof documentation, a flag store and
+	   a precedence.
+  RETURNS: TRUE iff condensing is applicable to <Clause>.
+           If <Document> is false the clause is 
+	   destructively changed else a condensed copy of 
+	   the clause is returned in <*Changed>.
+***********************************************************/
+{
+  LIST Indexes;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence) || 
+      (*Changed != (CLAUSE)NULL)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_Condensing : ");
+    misc_ErrorReport("Illegal input.\n");
+    misc_FinishErrorReport();    
+  }
+  clause_Check(Clause, Flags, Precedence);
+#endif
+
+  Indexes = cond_CondFast(Clause);
+
+  if (!list_Empty(Indexes)) {
+    if (flag_GetFlagValue(Flags, flag_PCON)) {
+      fputs("\nCondensing: ", stdout);
+      clause_Print(Clause);
+      fputs(" ==> ", stdout);
+    }
+    if (Document) {
+      CLAUSE Copy;
+      Copy = clause_Copy(Clause);
+      clause_DeleteLiterals(Copy, Indexes, Flags, Precedence);
+      red_DocumentCondensing(Copy, Indexes);
+      if (flag_GetFlagValue(Flags, flag_PCON))
+	clause_Print(Copy);
+      *Changed = Copy;
+    }
+    else {
+      clause_DeleteLiterals(Clause, Indexes, Flags, Precedence);
+      list_Delete(Indexes);
+      if (flag_GetFlagValue(Flags, flag_PCON))
+	clause_Print(Clause);
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+
+
+static void red_DocumentAssignmentEquationDeletion(CLAUSE Clause, LIST Indexes,
+						   NAT NonTrivClauseNumber)
+/*********************************************************
+  INPUT:   A clause and a list of literal indexes pointing to
+           redundant equations and the clause number of a clause
+	   implying a non-trivial domain.
+  RETURNS: Nothing.
+  MEMORY:  The <Indexes> list is consumed.
+**********************************************************/
+{
+  list_Delete(clause_ParentClauses(Clause));
+  list_Delete(clause_ParentLiterals(Clause));
+  clause_SetParentClauses(Clause, list_Nil());
+  clause_SetParentLiterals(Clause, Indexes);
+
+  clause_AddParentClause(Clause,clause_Number(Clause));  /* Has to be done before increasing it! */
+
+  clause_SetNumber(Clause, clause_IncreaseCounter());
+  clause_SetFromAssignmentEquationDeletion(Clause);
+
+  if (NonTrivClauseNumber != 0) {  /* Such a clause exists */
+    clause_AddParentClause(Clause, NonTrivClauseNumber);
+    clause_AddParentLiteral(Clause, 0); /* The non triv clause has exactly one negative literal */
+  }
+}
+
+
+static BOOL red_AssignmentEquationDeletion(CLAUSE Clause, FLAGSTORE Flags,
+					   PRECEDENCE Precedence, CLAUSE *Changed,
+					   NAT NonTrivClauseNumber,
+					   BOOL NonTrivDomain)
+/**********************************************************
+  INPUT:   A non-empty unshared clause, a flag store, a
+           precedence, the clause number of a clause
+	   implying a  non-trivial domain and a boolean
+	   flag indicating whether the current domain has
+	   more than one element.
+  RETURNS: TRUE iff equations are removed.
+           If the <DocProof> flag is false the clause is
+	   destructively changed else a copy of the clause 
+	   where redundant equations are removed is 
+	   returned in <*Changed>.
+***********************************************************/
+{
+  LIST Indexes;              /* List of indexes of redundant equations*/
+  NAT  i;
+  TERM LeftArg, RightArg;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence) ||
+      (*Changed != (CLAUSE)NULL) ||
+      (NonTrivDomain && NonTrivClauseNumber == 0) ||
+      (!NonTrivDomain && NonTrivClauseNumber > 0)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_AssignmentEquationDeletion: ");
+    misc_ErrorReport("Illegal input.\n");
+    misc_FinishErrorReport();    
+  }
+  clause_Check(Clause, Flags, Precedence);
+#endif
+
+  Indexes = list_Nil();
+
+  if (clause_ContainsNegativeEquations(Clause)) {
+    for (i = clause_FirstAntecedentLitIndex(Clause); i <= clause_LastAntecedentLitIndex(Clause); i++) {
+      if (clause_LiteralIsEquality(clause_GetLiteral(Clause,i))) {
+	LeftArg  = term_FirstArgument(clause_GetLiteralAtom(Clause,i));
+	RightArg = term_SecondArgument(clause_GetLiteralAtom(Clause,i));
+	if ((term_IsVariable(LeftArg) &&
+	     clause_NumberOfSymbolOccurrences(Clause, term_TopSymbol(LeftArg)) == 1) ||
+	    (term_IsVariable(RightArg) &&
+	     clause_NumberOfSymbolOccurrences(Clause, term_TopSymbol(RightArg)) == 1))
+	  Indexes = list_Cons((POINTER)i, Indexes);
+      }
+    }
+  }
+  else
+    if (NonTrivDomain && clause_ContainsPositiveEquations(Clause)) {
+      for (i = clause_FirstSuccedentLitIndex(Clause); i <= clause_LastSuccedentLitIndex(Clause); i++) {
+	if (clause_LiteralIsEquality(clause_GetLiteral(Clause,i))) {
+	  LeftArg  = term_FirstArgument(clause_GetLiteralAtom(Clause,i));
+	  RightArg = term_SecondArgument(clause_GetLiteralAtom(Clause,i));
+	  if ((term_IsVariable(LeftArg) &&
+	       clause_NumberOfSymbolOccurrences(Clause, term_TopSymbol(LeftArg)) == 1) ||
+	      (term_IsVariable(RightArg) &&
+	       clause_NumberOfSymbolOccurrences(Clause, term_TopSymbol(RightArg)) == 1))
+	    Indexes = list_Cons((POINTER)i, Indexes);
+	}
+      }
+    }
+
+  if (!list_Empty(Indexes)) {
+    if (flag_GetFlagValue(Flags, flag_PAED)) {
+      fputs("\nAED: ", stdout);
+      clause_Print(Clause);
+      fputs(" ==> ", stdout);
+    }
+    if (flag_GetFlagValue(Flags, flag_DOCPROOF)) {
+      CLAUSE Copy;
+      Copy = clause_Copy(Clause);
+      clause_DeleteLiterals(Copy, Indexes, Flags, Precedence);
+      red_DocumentAssignmentEquationDeletion(Copy, Indexes, NonTrivClauseNumber);
+      if (flag_GetFlagValue(Flags, flag_PAED))
+	clause_Print(Copy);
+      *Changed = Copy;
+    }
+    else {
+      clause_DeleteLiterals(Clause, Indexes, Flags, Precedence);
+      list_Delete(Indexes);
+      if (flag_GetFlagValue(Flags, flag_PAED))
+	clause_Print(Clause);
+    }
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+
+static BOOL red_Tautology(CLAUSE Clause, FLAGSTORE Flags, 
+			  PRECEDENCE Precedence)
+/**********************************************************
+  INPUT:   A non-empty clause, a flag store and a
+           precedence.
+  RETURNS: The boolean value TRUE if 'Clause' is a
+           tautology.
+***********************************************************/
+{
+  TERM  Atom;
+  int   i,j, la,n;
+  BOOL   Result;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_Tautology :");
+    misc_ErrorReport(" Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(Clause, Flags, Precedence);
+#endif
+  
+  la     = clause_LastAntecedentLitIndex(Clause);
+  n      = clause_Length(Clause);
+  Result = FALSE;
+
+  for (j = clause_FirstSuccedentLitIndex(Clause); j < n && !Result;  j++) {
+
+    Atom = clause_LiteralAtom(clause_GetLiteral(Clause, j));
+
+    if (fol_IsEquality(Atom) &&
+	!clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause, j)) &&
+	term_Equal(term_FirstArgument(Atom),term_SecondArgument(Atom)))
+      Result = TRUE;
+    
+    for (i = clause_FirstLitIndex(); i <= la && !Result; i++)
+      if (term_Equal(Atom, clause_LiteralAtom(clause_GetLiteral(Clause, i))))
+	Result = TRUE;
+  }
+
+
+  if (!Result && 
+      flag_GetFlagValue(Flags, flag_RTAUT) == flag_RTAUTSEMANTIC &&
+      clause_NumOfAnteLits(Clause) != 0 &&
+      clause_NumOfSuccLits(Clause) != 0) {
+    Result = cc_Tautology(Clause);
+  }
+
+  if (Result && flag_GetFlagValue(Flags, flag_PTAUT)) {
+    fputs("\nTautology: ", stdout);
+    clause_Print(Clause);
+  }
+  return Result;
+}
+
+static LITERAL red_GetMRResLit(LITERAL ActLit, SHARED_INDEX ShIndex)
+/**************************************************************
+  INPUT:   A literal and an Index.
+  RETURNS: The most valid clause with a complementary literal,
+           (CLAUSE)NULL, if no such clause exists.
+***************************************************************/
+{
+  LITERAL NextLit;
+  int     i;
+  CLAUSE  ActClause;
+  TERM    CandTerm;
+  LIST    LitScan;
+
+  NextLit   = (LITERAL)NULL;
+  ActClause = clause_LiteralOwningClause(ActLit);
+  i         = clause_LiteralGetIndex(ActLit);
+  CandTerm  = st_ExistGen(cont_LeftContext(),
+			  sharing_Index(ShIndex),
+			  clause_LiteralAtom(ActLit));
+
+  while (CandTerm) { /* First check units */
+    if (!term_IsVariable(CandTerm)) { /* Has to be an Atom! */
+      LitScan   = sharing_NAtomDataList(CandTerm); /* CAUTION !!! the List is not a copy */
+      while (!list_Empty(LitScan)) {
+	NextLit = list_Car(LitScan);
+	if (clause_LiteralsAreComplementary(ActLit,NextLit))
+	  if (clause_Length(clause_LiteralOwningClause(NextLit)) == 1 ||
+	      subs_SubsumesBasic(clause_LiteralOwningClause(NextLit),ActClause,
+				 clause_LiteralGetIndex(NextLit),i)) {
+	    st_CancelExistRetrieval();
+	    return NextLit;
+	  }
+	LitScan = list_Cdr(LitScan);
+      }
+    }
+    CandTerm = st_NextCandidate();
+  }
+  return (LITERAL)NULL;
+}
+
+static void red_DocumentMatchingReplacementResolution(CLAUSE Clause, LIST LitInds,
+						      LIST ClauseNums, LIST PLitInds)
+/*********************************************************
+  INPUT:   A clause, the involved literals indices in <Clause>,
+           the literal indices of the reduction literals
+	   and the clauses number.
+  RETURNS: Nothing.
+  MEMORY:  All input lists are consumed.
+**********************************************************/
+{
+  LIST   Scan,Help;
+
+  Help = list_Nil();
+
+  for (Scan=LitInds; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    Help = list_Cons((POINTER)clause_Number(Clause), Help);
+                                                /* Has to be done before increasing the clause number! */
+  }
+  list_Delete(clause_ParentClauses(Clause));
+  list_Delete(clause_ParentLiterals(Clause));
+  clause_SetParentClauses(Clause, list_Nconc(Help,ClauseNums));
+  clause_SetParentLiterals(Clause, list_Nconc(LitInds,PLitInds));
+  
+  clause_SetNumber(Clause, clause_IncreaseCounter());
+  clause_SetFromMatchingReplacementResolution(Clause);
+}
+
+static BOOL red_MatchingReplacementResolution(CLAUSE Clause, SHARED_INDEX ShIndex,
+					      FLAGSTORE Flags, PRECEDENCE Precedence,
+					      CLAUSE *Changed, int Level)
+/**************************************************************
+  INPUT:   A clause, an Index, a flag store, a precedence and a
+           split level indicating the need of a copy if
+	   <Clause> is reduced by a clause of higher split
+	   level than <Level>.
+  RETURNS: TRUE if reduction wrt the indexed clauses was
+           possible.
+           If the <DocProof> flag is true or the clauses used
+	   for reductions have a higher split level then a
+	   changed copy is returned in <*Changed>.
+	   Otherwise <Clause> is destructively changed.
+***************************************************************/
+{
+  CLAUSE  PClause,Copy;
+  LITERAL ActLit,PLit;
+  int     i, j, length;
+  LIST    ReducedBy,ReducedLits,PLits,Scan1,Scan2;
+  BOOL    Document;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence) ||
+      (*Changed != (CLAUSE)NULL)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_MatchingReplacementResolution:");
+    misc_ErrorReport(" Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(Clause, Flags, Precedence);
+#endif
+  
+  Copy        = Clause;
+  length      = clause_Length(Clause);
+  ReducedBy   = list_Nil();
+  ReducedLits = list_Nil();
+  PLits       = list_Nil();
+  i           = clause_FirstLitIndex();
+  j           = 0;
+  Document    = flag_GetFlagValue(Flags, flag_DOCPROOF);
+  
+  while (i < length) {
+    ActLit = clause_GetLiteral(Copy, i);
+    
+    if (!fol_IsEquality(clause_LiteralAtom(ActLit)) ||   /* Reduce with negative equations. */
+	clause_LiteralIsPositive(ActLit)) {
+      PLit = red_GetMRResLit(ActLit, ShIndex);
+      if (clause_LiteralExists(PLit)) {
+	if (list_Empty(PLits) && flag_GetFlagValue(Flags, flag_PMRR)) {
+	  fputs("\nFMatchingReplacementResolution: ", stdout);
+	  clause_Print(Copy);
+	}
+	PClause     = clause_LiteralOwningClause(PLit);
+	ReducedBy   = list_Cons((POINTER)clause_Number(PClause), ReducedBy);
+	PLits       = list_Cons((POINTER)clause_LiteralGetIndex(PLit),PLits);
+	ReducedLits = list_Cons((POINTER)(i+j), ReducedLits);
+	if (Copy == Clause &&
+	    (Document || prfs_SplitLevelCondition(clause_SplitLevel(PClause),clause_SplitLevel(Copy),Level)))
+	  Copy = clause_Copy(Clause);
+	clause_UpdateSplitDataFromPartner(Copy, PClause);	  
+	clause_DeleteLiteral(Copy,i, Flags, Precedence);
+	length--;
+	j++;
+      }
+      else
+	i++;
+    }
+    else
+      i++;
+  }
+  
+  if (!list_Empty(ReducedBy)) {
+    if (Document) {
+      ReducedBy   = list_NReverse(ReducedBy);
+      ReducedLits = list_NReverse(ReducedLits);
+      PLits       = list_NReverse(PLits);
+      red_DocumentMatchingReplacementResolution(Copy, ReducedLits, ReducedBy, PLits); /* Lists are consumed */
+      if (flag_GetFlagValue(Flags, flag_PMRR)) {
+	fputs(" ==> [ ", stdout);
+	for(Scan1=ReducedBy,Scan2=ReducedLits;!list_Empty(Scan1);
+	    Scan1=list_Cdr(Scan1),Scan2=list_Cdr(Scan2))
+	  printf("%d.%d ",(NAT)list_Car(Scan1),(NAT)list_Car(Scan2));
+	fputs("] ", stdout);
+	clause_Print(Copy);
+      }
+    }
+    else {
+      if (flag_GetFlagValue(Flags, flag_PMRR)) {
+	fputs(" ==> [ ", stdout);
+	for(Scan1=ReducedBy,Scan2=ReducedLits;!list_Empty(Scan1);
+	    Scan1=list_Cdr(Scan1),Scan2=list_Cdr(Scan2))
+	  printf("%d.%d ",(NAT)list_Car(Scan1),(NAT)list_Car(Scan2));
+	fputs("] ", stdout);
+	clause_Print(Copy);
+      }
+      list_Delete(ReducedBy);
+      list_Delete(ReducedLits);
+      list_Delete(PLits);
+    }
+    if (Copy != Clause)
+      *Changed = Copy;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void red_DocumentUnitConflict(CLAUSE Clause, LIST LitInds,
+				     LIST ClauseNums, LIST PLitInds)
+/*********************************************************
+  INPUT:   A clause, the involved literals indices and the clauses number.
+  RETURNS: Nothing.
+  MEMORY:  All input lists are consumed.
+**********************************************************/
+{
+  list_Delete(clause_ParentClauses(Clause));
+  list_Delete(clause_ParentLiterals(Clause));
+  clause_SetParentClauses(Clause, list_Nconc(list_List((POINTER)clause_Number(Clause)),ClauseNums));
+  clause_SetParentLiterals(Clause, list_Nconc(LitInds,PLitInds));
+  
+  clause_SetNumber(Clause, clause_IncreaseCounter());
+  clause_SetFromUnitConflict(Clause);
+}
+
+
+static BOOL red_UnitConflict(CLAUSE Clause, SHARED_INDEX ShIndex,
+			     FLAGSTORE Flags, PRECEDENCE Precedence,
+			     CLAUSE *Changed, int Level)
+/**************************************************************
+  INPUT:   A clause, an Index, a flag store  and a splitlevel
+           indicating the need of a copy if <Clause> is reduced
+	   by a clause of higher split level than <Level>.
+  RETURNS: TRUE if a unit conflict with <Clause> and the 
+           clauses in <ShIndex> happened.
+           If the <DocProof> flag is true or the clauses used for 
+	   reductions have a higher split level then a changed 
+	   copy is returned in <*Changed>.
+	   Otherwise <Clause> is destructively changed.
+***************************************************************/
+{
+  CLAUSE  PClause,Copy;
+  LITERAL ActLit,PLit;
+  LIST    Scan;
+  TERM    CandTerm;
+  BOOL    Document;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence) || (*Changed != (CLAUSE)NULL)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_ForwardUnitConflict :");
+    misc_ErrorReport(" Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(Clause, Flags, Precedence);
+#endif
+  
+  if (clause_Length(Clause) == 1) {
+    Copy     = Clause;
+    Document = flag_GetFlagValue(Flags, flag_DOCPROOF);
+    ActLit   = clause_GetLiteral(Copy, clause_FirstLitIndex());
+    PLit     = (LITERAL)NULL;
+    CandTerm = st_ExistUnifier(cont_LeftContext(), sharing_Index(ShIndex), cont_RightContext(),
+			       clause_LiteralAtom(ActLit));
+    while (PLit == (LITERAL)NULL && CandTerm) {
+      if (!term_IsVariable(CandTerm)) {
+	Scan = sharing_NAtomDataList(CandTerm); /* CAUTION !!! the List is not a copy */
+	while (!list_Empty(Scan)) {
+	  PLit = list_Car(Scan);
+	  if (clause_LiteralsAreComplementary(ActLit,PLit) &&
+	      clause_Length(clause_LiteralOwningClause(PLit)) == 1) {
+	    st_CancelExistRetrieval();
+	    Scan = list_Nil();
+	  }
+	  else {
+	    PLit = (LITERAL)NULL;
+	    Scan = list_Cdr(Scan);
+	  }
+	}
+      }
+      if (PLit == (LITERAL)NULL)
+	CandTerm = st_NextCandidate();
+    }
+
+    if (PLit == (LITERAL)NULL && fol_IsEquality(clause_LiteralAtom(ActLit))) {
+      TERM Atom;
+      Atom = term_Create(fol_Equality(),list_Reverse(term_ArgumentList(clause_LiteralAtom(ActLit))));
+      CandTerm = st_ExistUnifier(cont_LeftContext(), sharing_Index(ShIndex), cont_RightContext(), Atom);
+      while (PLit == (LITERAL)NULL && CandTerm) {
+	if (!term_IsVariable(CandTerm)) {
+	  Scan = sharing_NAtomDataList(CandTerm); /* CAUTION !!! the List is not a copy */
+	  while (!list_Empty(Scan)) {
+	    PLit = list_Car(Scan);
+	    if (clause_LiteralsAreComplementary(ActLit,PLit) &&
+		clause_Length(clause_LiteralOwningClause(PLit)) == 1) {
+	      st_CancelExistRetrieval();
+	      Scan = list_Nil();
+	    }
+	    else {
+	      PLit = (LITERAL)NULL;
+	      Scan = list_Cdr(Scan);
+	    }
+	  }
+	}
+	if (PLit == (LITERAL)NULL)
+	  CandTerm = st_NextCandidate();
+      }
+      list_Delete(term_ArgumentList(Atom));
+      term_Free(Atom);
+    }
+      
+    if (clause_LiteralExists(PLit)) {
+      if (flag_GetFlagValue(Flags, flag_PUNC)) {
+	fputs("\nUnitConflict: ", stdout);
+	clause_Print(Copy);
+      }
+      PClause     = clause_LiteralOwningClause(PLit);
+      if (Copy == Clause &&
+	  (Document || prfs_SplitLevelCondition(clause_SplitLevel(PClause),clause_SplitLevel(Copy),Level)))
+	Copy = clause_Copy(Clause);
+      clause_UpdateSplitDataFromPartner(Copy, PClause);	  
+      clause_DeleteLiteral(Copy,clause_FirstLitIndex(), Flags, Precedence);
+      if (Document) 
+	red_DocumentUnitConflict(Copy, list_List((POINTER)clause_FirstLitIndex()), 
+				 list_List((POINTER)clause_Number(PClause)), 
+				 list_List((POINTER)clause_FirstLitIndex()));
+      if (flag_GetFlagValue(Flags, flag_PUNC)) {
+	printf(" ==> [ %d.%d ]", clause_Number(PClause), clause_FirstLitIndex());	
+	clause_Print(Copy);
+      }
+      if (Copy != Clause)
+	*Changed = Copy;
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+
+static CLAUSE red_ForwardSubsumer(CLAUSE RedCl, SHARED_INDEX ShIndex,
+				  FLAGSTORE Flags, PRECEDENCE Precedence)
+/**********************************************************
+  INPUT:   A pointer to a non-empty clause, an index of 
+           clauses, a flag store and a precedence.
+  RETURNS: A clause that subsumes <RedCl>, or NULL if no such
+           clause exists.
+***********************************************************/
+{
+  TERM    Atom,AtomGen;
+  CLAUSE  CandCl;
+  LITERAL CandLit;
+  LIST    LitScan;
+  int     i, lc, fa, la, fs, ls;
+
+#ifdef CHECK
+  if (!clause_IsClause(RedCl, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_ForwardSubsumer:");
+    misc_ErrorReport(" Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(RedCl, Flags, Precedence);
+#endif
+
+  lc = clause_LastConstraintLitIndex(RedCl);
+  fa = clause_FirstAntecedentLitIndex(RedCl);
+  la = clause_LastAntecedentLitIndex(RedCl);
+  fs = clause_FirstSuccedentLitIndex(RedCl);
+  ls = clause_LastSuccedentLitIndex(RedCl);
+
+  for (i = 0; i <= ls; i++) {
+    Atom    = clause_GetLiteralAtom(RedCl, i);
+    AtomGen = st_ExistGen(cont_LeftContext(), sharing_Index(ShIndex), Atom);
+
+    while (AtomGen) {
+      if (!term_IsVariable(AtomGen)) {
+	for (LitScan = sharing_NAtomDataList(AtomGen);
+	     !list_Empty(LitScan);
+	     LitScan = list_Cdr(LitScan)) {
+	  CandLit = list_Car(LitScan);
+	  CandCl  = clause_LiteralOwningClause(CandLit);
+
+	  if (CandCl != RedCl &&
+	      clause_GetLiteral(CandCl,clause_FirstLitIndex()) == CandLit &&
+	      /* Literals must be from same part of the clause */
+	      ((i<=lc && clause_LiteralIsFromConstraint(CandLit)) ||
+	       (i>=fa && i<=la && clause_LiteralIsFromAntecedent(CandLit)) ||
+	       (i>=fs && clause_LiteralIsFromSuccedent(CandLit))) &&
+	      subs_SubsumesBasic(CandCl, RedCl, clause_FirstLitIndex(), i)) {
+	    st_CancelExistRetrieval();
+	    return (CandCl);
+	  }
+	}
+      }
+      AtomGen = st_NextCandidate();
+    }
+
+    if (fol_IsEquality(Atom) && 
+	clause_LiteralIsNotOrientedEquality(clause_GetLiteral(RedCl,i))) {
+      Atom = term_Create(fol_Equality(),list_Reverse(term_ArgumentList(Atom)));
+      AtomGen = st_ExistGen(cont_LeftContext(), sharing_Index(ShIndex), Atom);
+      while (AtomGen) {
+	if (!term_IsVariable(AtomGen)) {
+	  for (LitScan = sharing_NAtomDataList(AtomGen);
+	       !list_Empty(LitScan);
+	       LitScan = list_Cdr(LitScan)) {
+	    CandLit = list_Car(LitScan);
+	    CandCl  = clause_LiteralOwningClause(CandLit);
+	    if (CandCl != RedCl &&
+		clause_GetLiteral(CandCl,clause_FirstLitIndex()) == CandLit &&
+		/* Literals must be from same part of the clause */
+		((i<=lc && clause_LiteralIsFromConstraint(CandLit)) ||
+		 (i>=fa && i<=la && clause_LiteralIsFromAntecedent(CandLit)) ||
+		 (i>=fs && clause_LiteralIsFromSuccedent(CandLit))) &&
+		subs_SubsumesBasic(CandCl, RedCl, clause_FirstLitIndex(), i)) {
+	      st_CancelExistRetrieval();
+	      list_Delete(term_ArgumentList(Atom));
+	      term_Free(Atom);
+	      return (CandCl);
+	    }
+	  }
+	}
+	AtomGen = st_NextCandidate();
+      }
+      list_Delete(term_ArgumentList(Atom));
+      term_Free(Atom);
+    }
+  }
+
+  return((CLAUSE)NULL);
+}
+
+
+static CLAUSE red_ForwardSubsumption(CLAUSE RedClause, SHARED_INDEX ShIndex, 
+				     FLAGSTORE Flags, PRECEDENCE Precedence)
+/**********************************************************
+  INPUT:   A clause, an index of clauses, a flag store and
+           a precedence.
+  RETURNS: The clause <RedClause> is subsumed by in <ShIndex>.
+***********************************************************/
+{ 
+  CLAUSE Subsumer;
+
+#ifdef CHECK
+  if (!clause_IsClause(RedClause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_ForwardSubsumption:");
+    misc_ErrorReport(" Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(RedClause, Flags, Precedence);
+#endif
+
+  Subsumer = red_ForwardSubsumer(RedClause, ShIndex, Flags, Precedence);
+
+  if (flag_GetFlagValue(Flags, flag_PSUB) && Subsumer) {
+    fputs("\nFSubsumption: ", stdout);
+    clause_Print(RedClause);
+    printf(" by %d %d ",clause_Number(Subsumer),clause_SplitLevel(Subsumer));
+  }
+
+  return Subsumer;
+}
+
+
+static void red_DocumentRewriting(CLAUSE Clause, int i, CLAUSE Rule, int ri)
+/*********************************************************
+  INPUT:   Two clauses and the literal indices involved in the rewrite step.
+  RETURNS: Nothing.
+  EFFECT:  Documentation in <Clause> is set.
+**********************************************************/
+{
+  list_Delete(clause_ParentClauses(Clause));
+  list_Delete(clause_ParentLiterals(Clause));
+  clause_SetParentClauses(Clause,
+			  list_List((POINTER)clause_Number(Clause)));
+  /* Has to be done before increasing the number! */
+
+  clause_SetParentLiterals(Clause, list_List((POINTER)i));
+  clause_NewNumber(Clause);
+  clause_SetFromRewriting(Clause);
+
+  clause_AddParentClause(Clause,clause_Number(Rule));
+  clause_AddParentLiteral(Clause,ri);
+}
+
+
+static void red_DocumentFurtherRewriting(CLAUSE Clause, int i, CLAUSE Rule, int ri)
+/*********************************************************
+  INPUT:   Two clauses and the literal indices involved in the rewrite step.
+  RETURNS: Nothing.
+  EFFECT:  Documentation in <Clause> is set.
+**********************************************************/
+{
+  clause_AddParentClause(Clause,
+			 (int) list_Car(list_Cdr(clause_ParentClauses(Clause))));
+  clause_AddParentLiteral(Clause, i);
+  clause_AddParentClause(Clause, clause_Number(Rule));
+  clause_AddParentLiteral(Clause, ri);
+}
+
+
+static BOOL red_RewriteRedUnitClause(CLAUSE RedClause, SHARED_INDEX ShIndex,
+				     FLAGSTORE Flags, PRECEDENCE Precedence,
+				     CLAUSE *Changed, int Level)
+/**************************************************************
+  INPUT:   A unit (!) clause, an Index, a flag store, a
+           precedence and a split level indicating the need of
+	   a copy  if <Clause> is reduced by a clause of higher
+	   split level than <Level>.
+  RETURNS: TRUE iff rewriting was possible.
+           If the <DocProof> flag is true or the split level of
+	   the rewrite rule is higher a copy of RedClause that
+	   is rewritten wrt. the indexed clauses is returned in 
+	   <*Changed>.
+           Otherwise the clause is destructively rewritten.
+***************************************************************/
+{
+  TERM   RedAtom, RedTermS;
+  int    B_Stack;
+  BOOL   Rewritten, Result, Oriented, Renamed, Document;
+  TERM   TermS,PartnerEq;
+  LIST   EqList,EqScan,LitScan;
+  CLAUSE Copy;
+
+#ifdef CHECK
+  if (!clause_IsClause(RedClause, Flags, Precedence) ||
+      *Changed != (CLAUSE)NULL ||
+      clause_Length(RedClause) != 1) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_RewriteRedUnitClause :");
+    misc_ErrorReport(" Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(RedClause, Flags, Precedence);
+#endif
+
+  Result    = FALSE;
+  Renamed   = FALSE;
+  Copy      = RedClause;
+  RedAtom   = clause_GetLiteralAtom(Copy, clause_FirstLitIndex());
+  Rewritten = TRUE;
+  Document  = flag_GetFlagValue(Flags, flag_DOCPROOF);    
+
+  /* Don't apply this rule on constraint or propositional literals */
+  if (clause_FirstLitIndex() <= clause_LastConstraintLitIndex(RedClause) ||
+      list_Empty(term_ArgumentList(RedAtom)))
+    return Result;
+
+  if (term_StampOverflow(red_STAMPID))
+    term_ResetTermStamp(clause_LiteralSignedAtom(clause_GetLiteral(RedClause, clause_FirstLitIndex())));
+  term_StartStamp();
+
+  while (Rewritten) {
+    Rewritten = FALSE;
+    B_Stack = stack_Bottom();
+    sharing_PushListOnStackNoStamps(term_ArgumentList(RedAtom));
+    
+    while (!stack_Empty(B_Stack)) {
+      RedTermS = (TERM)stack_PopResult();
+      TermS    = st_ExistGen(cont_LeftContext(), sharing_Index(ShIndex), RedTermS);
+      while (TermS && !Rewritten) {
+	EqList = term_SupertermList(TermS);
+	for (EqScan = EqList; !list_Empty(EqScan) && !Rewritten;
+	     EqScan = list_Cdr(EqScan)) {
+	  PartnerEq = list_Car(EqScan);
+	  if (fol_IsEquality(PartnerEq)) {
+	    CLAUSE  RewriteClause;
+	    LITERAL RewriteLit;
+	    TERM    Right;
+
+	    if (TermS == term_FirstArgument(PartnerEq))
+	      Right = term_SecondArgument(PartnerEq);
+	    else
+	      Right = term_FirstArgument(PartnerEq);
+
+	    for (LitScan = sharing_NAtomDataList(PartnerEq); 
+		 !list_Empty(LitScan) && !Rewritten;
+		 LitScan = list_Cdr(LitScan)) {
+	      RewriteLit    = list_Car(LitScan);
+	      RewriteClause = clause_LiteralOwningClause(RewriteLit);
+	      if (clause_LiteralIsPositive(RewriteLit) &&
+		  clause_Length(RewriteClause) == 1) {
+		Oriented = (clause_LiteralIsOrientedEquality(RewriteLit) && 
+			    TermS == term_FirstArgument(PartnerEq));
+		if (!Oriented && !clause_LiteralIsOrientedEquality(RewriteLit)) { 
+		  Renamed = TRUE;                            /* If oriented, no renaming needed! */
+		  term_StartMaxRenaming(clause_MaxVar(RewriteClause));
+		  term_Rename(RedAtom); /* Renaming destructive, no extra match needed !! */
+		  Oriented = ord_ContGreater(cont_LeftContext(), TermS,
+					     cont_LeftContext(), Right,
+					     Flags, Precedence);
+		  
+		  /*if (Oriented) {
+		    fputs("\n\n\tRedAtom: ",stdout);term_PrintPrefix(RedAtom);
+		    fputs("\n\tSubTerm: ",stdout);term_PrintPrefix(RedTermS);
+		    fputs("\n\tGenTerm: ",stdout);term_PrintPrefix(TermS);
+		    fputs("\n\tGenRight: ",stdout);term_PrintPrefix(Right);
+		    putchar('\n');cont_PrintCurrentTrail();putchar('\n');
+		    }*/
+		}
+		if (Oriented) {
+		  TERM   TermT;
+		  
+		  if (RedClause == Copy &&
+		      (Document || 
+		       prfs_SplitLevelCondition(clause_SplitLevel(RewriteClause),
+						clause_SplitLevel(RedClause),Level))) {
+		    Copy    = clause_Copy(RedClause);
+		    RedAtom = clause_GetLiteralAtom(Copy, clause_FirstLitIndex());
+		  }
+		  
+		  if (!Result)
+		    if (flag_GetFlagValue(Flags, flag_PREW)) {
+		      fputs("\nFRewriting: ", stdout);
+		      clause_Print(Copy);
+		      fputs(" ==>[ ", stdout);
+		    }
+		  
+		  if (Document) {
+		    if (!Result)
+		      red_DocumentRewriting(Copy, clause_FirstLitIndex(),
+					    RewriteClause, clause_FirstLitIndex());
+		    else
+		      red_DocumentFurtherRewriting(Copy, clause_FirstLitIndex(), 
+						   RewriteClause, clause_FirstLitIndex());
+		  }
+		  Result = TRUE;
+		  TermT  = cont_ApplyBindingsModuloMatching(cont_LeftContext(), term_Copy(Right), TRUE);
+		  if (cont_BindingsAreRenamingModuloMatching(cont_RightContext()))
+		    term_SetTermSubtermStamp(TermT);
+		  term_ReplaceSubtermBy(RedAtom, RedTermS, TermT);
+		  Rewritten = TRUE;
+		  clause_UpdateSplitDataFromPartner(Copy, RewriteClause);
+		  term_Delete(TermT);
+		  stack_SetBottom(B_Stack);
+		  
+		  if (flag_GetFlagValue(Flags, flag_PREW))
+		    printf("%d.%d ",clause_Number(RewriteClause), clause_FirstLitIndex());
+		  clause_UpdateWeight(Copy, Flags);
+		}
+	      }
+	    }
+	  }
+	}
+	if (!Rewritten)
+	  TermS = st_NextCandidate();
+      }
+      st_CancelExistRetrieval();
+      if (!Rewritten)
+	term_SetTermStamp(RedTermS);
+    }
+  }
+  term_StopStamp(); 
+
+  if (Result) {
+    clause_OrientAndReInit(Copy, Flags, Precedence);
+    if (Copy != RedClause)
+      clause_OrientAndReInit(RedClause, Flags, Precedence);
+    if (flag_GetFlagValue(Flags, flag_PREW)) {
+      fputs("] ", stdout);
+      clause_Print(Copy);
+    }
+    if (Copy != RedClause)
+      *Changed = Copy;
+  }
+  else
+    if (Renamed)
+      clause_OrientAndReInit(Copy, Flags, Precedence);
+	
+      
+#ifdef CHECK
+  clause_Check(Copy, Flags, Precedence);
+  clause_Check(RedClause, Flags, Precedence);
+#endif
+  
+  return Result;
+}
+
+
+static BOOL red_RewriteRedClause(CLAUSE RedClause, SHARED_INDEX ShIndex,
+				 FLAGSTORE Flags, PRECEDENCE Precedence,
+				 CLAUSE *Changed, int Level)
+/**************************************************************
+  INPUT:   A clause, an Index, a flag store, a precedence and
+           a split level indicating the need of a copy if
+	   <Clause> is reduced by a clause of higher split
+	   level than <Level>.
+  RETURNS: NULL, if no rewriting was possible.
+           If the <DocProof> flag is true or the split level of
+	   the rewrite rule is higher a copy of RedClause
+	   that is rewritten wrt. the indexed clauses.
+	   Otherwise the clause is destructively rewritten and
+	   returned.
+***************************************************************/
+{
+  TERM   RedAtom, RedTermS;
+  int    B_Stack;
+  int    ci, length;
+  BOOL   Rewritten, Result, Document;
+  TERM   TermS,PartnerEq;
+  LIST   EqScan,LitScan;
+  CLAUSE Copy;
+
+#ifdef CHECK
+  if (!clause_IsClause(RedClause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_RewriteRedClause :");
+    misc_ErrorReport(" Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(RedClause, Flags, Precedence);
+#endif
+  
+  length   = clause_Length(RedClause);
+  Document = flag_GetFlagValue(Flags, flag_DOCPROOF); 
+
+  if (length == 1)
+    return red_RewriteRedUnitClause(RedClause, ShIndex, Flags, Precedence,
+				    Changed, Level);
+
+  Result = FALSE;
+  Copy   = RedClause;
+
+  /* Don't apply this rule on constraint literals! */
+  for (ci = clause_FirstAntecedentLitIndex(RedClause); ci < length; ci++) {
+    Rewritten  = TRUE;
+    if (!list_Empty(term_ArgumentList(clause_GetLiteralAtom(Copy, ci)))) {
+      while (Rewritten) {
+	Rewritten = FALSE;
+	RedAtom   = clause_GetLiteralAtom(Copy, ci);
+
+	B_Stack = stack_Bottom();
+	/* push subterms on stack except variables */
+	sharing_PushListReverseOnStack(term_ArgumentList(RedAtom));
+
+	while (!stack_Empty(B_Stack))  {
+	  RedTermS = (TERM)stack_PopResult();
+	  TermS    = st_ExistGen(cont_LeftContext(), sharing_Index(ShIndex), RedTermS);
+
+	  while (TermS && !Rewritten) {
+	    /* A variable can't be greater than any other term, */
+	    /* so don't consider any variables here             */
+	    if (!term_IsVariable(TermS)) {
+	      EqScan = term_SupertermList(TermS);
+
+	      for ( ; !list_Empty(EqScan) && !Rewritten;
+		    EqScan = list_Cdr(EqScan)) {
+		PartnerEq = list_Car(EqScan);
+		if (fol_IsEquality(PartnerEq) &&
+		    (term_FirstArgument(PartnerEq) == TermS)) {
+		  CLAUSE  RewriteClause;
+		  LITERAL RewriteLit;
+		  int     ri;
+		  
+		  for (LitScan = sharing_NAtomDataList(PartnerEq); 
+		       !list_Empty(LitScan) && !Rewritten;
+		       LitScan = list_Cdr(LitScan)) {
+		    RewriteLit    = list_Car(LitScan);
+		    RewriteClause = clause_LiteralOwningClause(RewriteLit);
+		    ri            = clause_LiteralGetIndex(RewriteLit);
+		    
+		    if (clause_LiteralIsPositive(RewriteLit) &&
+			clause_LiteralIsOrientedEquality(RewriteLit) &&
+			subs_SubsumesBasic(RewriteClause, Copy, ri, ci)) {
+		      TERM   TermT;
+		      
+		      if (RedClause == Copy &&
+			  (Document || 
+			   prfs_SplitLevelCondition(clause_SplitLevel(RewriteClause),
+						    clause_SplitLevel(RedClause),Level))) {
+			Copy    = clause_Copy(RedClause);
+			RedAtom = clause_GetLiteralAtom(Copy, ci);
+		      }
+		      
+		      if (!Result) {
+			if (flag_GetFlagValue(Flags, flag_PREW)) {
+			  fputs("\nFRewriting: ", stdout);
+			  clause_Print(Copy);
+			  fputs(" ==>[ ", stdout);
+			}
+		      }
+		      
+		      if (Document) {
+			if (!Result)
+			  red_DocumentRewriting(Copy, ci, RewriteClause, ri);
+			else
+			  red_DocumentFurtherRewriting(Copy,ci,RewriteClause,ri);
+		      }
+		      Result = TRUE;
+		      /* Since <TermS> is the bigger term of an oriented   */
+		      /* equation and all variables in <TermS> are bound,  */
+		      /* all variables in the smaller term are bound, too. */
+		      /* So the strict version of cont_Apply... will work. */
+		      TermT  = cont_ApplyBindingsModuloMatching(cont_LeftContext(),
+								term_Copy(term_SecondArgument(PartnerEq)),
+								TRUE);
+
+		      /* No variable renaming is necessary before creation   */
+		      /* of bindings and replacement of subterms because all */
+		      /* variables of <TermT> are from <RedClause>/<Copy>.   */
+		      term_ReplaceSubtermBy(RedAtom, RedTermS, TermT);
+		      Rewritten = TRUE;
+		      clause_UpdateSplitDataFromPartner(Copy,RewriteClause);
+		      term_Delete(TermT);
+		      stack_SetBottom(B_Stack);
+		      
+		      if (flag_GetFlagValue(Flags, flag_PREW))
+			printf("%d.%d ",clause_Number(RewriteClause), ri);
+		      clause_UpdateWeight(Copy, Flags);
+		    }
+		  }
+		}
+	      }
+	    }
+	    if (!Rewritten)
+	      TermS = st_NextCandidate();
+	  }
+	  st_CancelExistRetrieval();
+	}
+      }
+    }
+  }
+  if (Result) {
+    clause_OrientAndReInit(Copy, Flags, Precedence);
+    if (flag_GetFlagValue(Flags, flag_PREW)) {
+      fputs("] ", stdout);
+      clause_Print(Copy);
+    }
+    if (Copy != RedClause) {
+      clause_OrientAndReInit(RedClause, Flags, Precedence);
+      *Changed = Copy;
+    }
+  }
+
+#ifdef CHECK
+  clause_Check(Copy, Flags, Precedence);
+  clause_Check(RedClause, Flags, Precedence);
+#endif
+
+  return Result;
+}
+
+
+/**************************************************************/
+/* FORWARD CONTEXTUAL REWRITING                               */
+/**************************************************************/
+
+static BOOL red_LeftTermOfEquationIsStrictlyMaximalTerm(CLAUSE Clause,
+							LITERAL Equation,
+							FLAGSTORE Flags,
+							PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, a literal of the clause, that is an
+           oriented equation, a flag store and a precedence.
+  RETURNS: TRUE, iff the bigger (i.e. left) term of the equation
+           is the strictly maximal term of the clause.
+	   A term s is strictly maximal in a clause, iff for every atom
+	   u=v (A=tt) of the clause s > u and s > v (s > A).
+***************************************************************/
+{
+  int     i, except, last;
+  TERM    LeftTerm, Atom;
+  LITERAL ActLit;
+
+#ifdef CHECK
+  if (!clause_LiteralIsOrientedEquality(Equation)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_LeftTermOfEquationIsStrictlyMaximalTerm: ");
+    misc_ErrorReport("literal is not oriented");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  LeftTerm = term_FirstArgument(clause_LiteralSignedAtom(Equation));
+  except   = clause_LiteralGetIndex(Equation);
+
+  /* Compare <LeftTerm> with all terms in the clause */
+  last = clause_LastLitIndex(Clause);
+  for (i = clause_FirstLitIndex() ; i <= last; i++) {
+    if (i != except) {
+      ActLit = clause_GetLiteral(Clause, i);
+      Atom = clause_LiteralAtom(ActLit);
+      if (fol_IsEquality(Atom)) {
+	/* Atom is an equation */
+	if (ord_Compare(LeftTerm, term_FirstArgument(Atom), Flags, Precedence)
+	    != ord_GREATER_THAN ||
+	    (!clause_LiteralIsOrientedEquality(ActLit) &&
+	     ord_Compare(LeftTerm, term_SecondArgument(Atom), Flags, Precedence)
+	     != ord_GREATER_THAN))
+	  /* Compare only with left (i.e. greater) subterm if the atom is */
+	  /* an oriented equation. */
+	  return FALSE;
+      } else {
+	/* Atom is not an equation */
+	if (ord_Compare(LeftTerm, Atom, Flags, Precedence) != ord_GREATER_THAN)
+	  return FALSE;
+      }
+    }
+  }
+  return TRUE;
+}
+
+
+static void red_CRwCalculateAdditionalParents(CLAUSE Reduced,
+					      LIST RedundantClauses,
+					      CLAUSE Subsumer,
+					      int OriginalClauseNumber)
+/**************************************************************
+  INPUT:   A clause that was just reduced by forward reduction,
+           a list of intermediate clauses that were derived from
+	   the original clause, a clause that subsumes <Reduced>
+	   (NULL, if <Reduced> is not subsumed), and the clause
+	   number of <Reduced> before it was reduced.
+  RETURNS: Nothing.
+  EFFECT:  This function collects the information about parent
+           clauses and parent literals that is necessary for
+	   proof documentation for Contextual Rewriting
+	   and sets the parent information of <Reduced> accordingly.
+	   The clause <Reduced> was derived in several steps
+	   C1 -> C2 -> ... Cn -> <Reduced> from some clause C1.
+           <RedundantClauses> contains all those clauses C1, ..., Cn.
+	   This function first collects the parent information from
+	   the clauses C1, C2, ..., Cn, <Reduced>. All those clauses
+	   were needed to derive <Reduced>, but for proof documentation
+	   of the rewriting step we have to delete the numbers of
+	   all clauses C1,...,Cn,Reduced.
+
+	   As a simplification this function doesn't set the
+	   correct parent literals. It simply assumes that every
+	   reduction step was done by literal 0.
+	   This isn't a problem since only the correct parent
+	   clause numbers are really needed for proof documentation.
+***************************************************************/
+{
+  LIST Parents, Scan;
+  int  ActNum;
+  
+  /* First collect all parent clause numbers from the redundant clauses. */
+  /* Also add number of <Subsumer> if it exists. */
+  Parents = clause_ParentClauses(Reduced);
+  clause_SetParentClauses(Reduced, list_Nil());
+  for (Scan = RedundantClauses; !list_Empty(Scan); Scan = list_Cdr(Scan))
+    Parents = list_Append(clause_ParentClauses(list_Car(Scan)), Parents);
+  if (Subsumer != NULL)
+    Parents = list_Cons((POINTER)clause_Number(Subsumer), Parents);
+
+  /* Now delete <OriginalClauseNumber> and the numbers of all clauses */
+  /* that were derived from it.                                       */
+  Parents = list_PointerDeleteElement(Parents, (POINTER) OriginalClauseNumber);
+  for (Scan = RedundantClauses; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    ActNum = clause_Number(list_Car(Scan));
+    Parents = list_PointerDeleteElement(Parents, (POINTER) ActNum);
+  }
+
+  /* Finally set data of result clause <Reduced>. */
+  Parents = list_PointerDeleteDuplicates(Parents);
+  clause_SetParentClauses(Reduced, Parents);
+  /* Build list of literal numbers: in this simple version we just build   */
+  /* a list with the same length as the parent clauses containing only the */
+  /* literal indices 0. */
+  Parents = list_Copy(Parents);
+  for (Scan = Parents; !list_Empty(Scan); Scan = list_Cdr(Scan))
+    list_Rplaca(Scan, (POINTER)0);
+  list_Delete(clause_ParentLiterals(Reduced));
+  clause_SetParentLiterals(Reduced, Parents);
+}
+
+
+static BOOL red_LiteralIsDefinition(LITERAL Literal)
+/**************************************************************
+  INPUT:   A literal.
+  RETURNS: TRUE, iff the literal is a definition, i.e. an equation x=t,
+           where x is a variable and x doesn't occur in t.
+           The function needs time O(1), it is independent of the size
+	   of the literal.
+  CAUTION: The orientation of the literal must be correct.
+***************************************************************/
+{
+  TERM Atom;
+
+  Atom = clause_LiteralAtom(Literal);
+  if (fol_IsEquality(Atom) &&
+      !clause_LiteralIsOrientedEquality(Literal) &&
+      (term_IsVariable(term_FirstArgument(Atom)) ||
+       term_IsVariable(term_SecondArgument(Atom))) &&
+      !term_VariableEqual(term_FirstArgument(Atom),
+			  term_SecondArgument(Atom)))
+    return TRUE;
+  else
+    return FALSE;
+}
+
+
+static BOOL red_PropagateDefinitions(CLAUSE Clause, TERM LeadingTerm,
+				     FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, a term, a flag store and a precedence.
+  RETURNS: TRUE, iff any definitions in <Clause> where propagated,
+           false otherwise.
+
+	   Here, a definitions means a negative literal x=t, where
+	   x is a variable and x doesn't occur in t.
+           Definitions are only propagated if all terms in the
+	   resulting clause would be smaller than <LeadingTerm>.
+	   The flag store and the precedence are only needed for
+	   term comparisons with respect to the reduction ordering.
+  CAUTION: <Clause> is changed destructively!
+***************************************************************/
+{
+  LITERAL Lit;
+  TERM    Term, Atom;
+  SYMBOL  Var;
+  int     i, last, j, lj;
+  BOOL    success, applied;
+  LIST    litsToRemove;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_PropagateDefinitions: clause is corrupted.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  applied      = FALSE;
+  litsToRemove = list_Nil();    /* collect indices of redundant literals */
+  last         = clause_LastAntecedentLitIndex(Clause);
+
+  for (i = clause_FirstAntecedentLitIndex(Clause); i <= last; i++) {
+    Lit = clause_GetLiteral(Clause, i);
+
+    if (red_LiteralIsDefinition(Lit)) {
+      /* <Lit> is an equation x=t where the variable x doesn't occur in t. */
+
+      Term = term_FirstArgument(clause_LiteralAtom(Lit));
+      if (term_IsVariable(Term)) {
+	Var  = term_TopSymbol(Term);
+	Term = term_SecondArgument(clause_LiteralAtom(Lit));
+      } else {
+	Var = term_TopSymbol(term_SecondArgument(clause_LiteralAtom(Lit)));
+      }
+
+      /* Establish variable binding x -> t in context */
+#ifdef CHECK
+      cont_SaveState();
+#endif
+      cont_StartBinding();
+      cont_CreateBinding(cont_LeftContext(), Var, cont_InstanceContext(), Term);
+
+      /* Check that for each literal u=v (A=tt) the conditions             */
+      /* u{x->t} < LeadingTerm and v{x->t} < LeadingTerm (A < LeadingTerm) */
+      /* hold. */
+      success = TRUE;
+      Lit     = NULL;
+      lj      = clause_LastLitIndex(Clause);
+
+      for (j = clause_FirstLitIndex(); j <= lj && success; j++) {
+	if (j != i) {
+	  success = FALSE;
+	  Lit  = clause_GetLiteral(Clause, j);
+	  Atom = clause_LiteralAtom(Lit);
+	  if (fol_IsEquality(Atom)) {
+	    /* Atom is an equation */
+	    if (ord_ContGreater(cont_InstanceContext(), LeadingTerm,
+				cont_LeftContext(), term_FirstArgument(Atom),
+				Flags, Precedence) &&
+		(clause_LiteralIsOrientedEquality(Lit) ||
+		 ord_ContGreater(cont_InstanceContext(), LeadingTerm,
+				 cont_LeftContext(), term_SecondArgument(Atom),
+				 Flags, Precedence)))
+	      /* Compare only with left (i.e. greater) subterm if the atom is */
+	      /* an oriented equation. */
+	      success = TRUE;
+	  } else {
+	    /* Atom is not an equation */
+	    if (ord_ContGreater(cont_InstanceContext(), LeadingTerm,
+				cont_LeftContext(), Atom, Flags, Precedence))
+	      success = TRUE;
+	  }
+	}
+      }
+
+      cont_BackTrack();
+
+#ifdef CHECK
+      cont_CheckState();
+#endif
+ 
+      if (success) {
+	/* Replace variable <Var> in <Clause> by <Term> */
+	clause_ReplaceVariable(Clause, Var, Term);
+	/* The clause literals aren't reoriented here. For the detection of */
+	/* definitions it suffices to know the non-oriented literals in the */
+	/* original clause. */
+	litsToRemove = list_Cons((POINTER)i, litsToRemove);
+	applied = TRUE;
+      }
+    }
+  }
+  
+  if (applied) {
+    /* Now remove the definition literals. */
+    clause_DeleteLiterals(Clause, litsToRemove, Flags, Precedence);
+    list_Delete(litsToRemove);
+
+    /* Equations have to be reoriented. */
+    clause_OrientEqualities(Clause, Flags, Precedence);
+
+#ifdef CHECK
+    if (!clause_IsClause(Clause, Flags, Precedence)) {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In red_PropagateDefinitions: clause is corrupted ");
+      misc_ErrorReport("after propagation of definitions");
+      misc_FinishErrorReport();
+    }
+#endif
+  }
+
+  return applied;
+}
+
+
+static CLAUSE red_CRwLitTautologyCheck(PROOFSEARCH Search, CLAUSE RedClause,
+				       int Except, CLAUSE RuleClause, int i,
+				       TERM LeadingTerm, NAT Mode)
+/**************************************************************
+  INPUT:   A proof search object, two clauses, two literal indices
+           (one per clause), a mode defining the clause index used
+	   for intermediate reductions.
+  RETURNS: NULL, if the tautology check for literal <i> in <RuleClause>
+           failed.
+
+           If the test succeeds an auxiliary clause is returned that
+	   contains part of the splitting information for the current
+	   rewriting step. If the 'DocProof' flag is set, the necessary
+	   parent information is set, too.
+  MEMORY:  Remember to delete the returned clause!
+***************************************************************/
+{
+  FLAGSTORE  Flags;
+  PRECEDENCE Precedence;
+  CLAUSE     aux, NewClause;
+  LITERAL    Lit;
+  TERM       Atom;
+  BOOL       DocProof, Negative, Redundant;
+  LIST       NegLits, PosLits, RedundantList;
+  int        OrigNum;
+  
+  Flags      = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+  DocProof   = flag_GetFlagValue(Flags, flag_DOCPROOF);
+  
+  Lit      = clause_GetLiteral(RuleClause, i);
+  Atom     = clause_LiteralAtom(Lit);
+  Negative = clause_LiteralIsNegative(Lit);
+
+#ifdef CRW_DEBUG
+  printf("\n  ----------\n  ");
+  if (Negative)
+    printf((i <= clause_LastConstraintLitIndex(RuleClause)) ? "Cons" : "Ante");
+  else
+    printf("Succ");
+  printf(" aux = ");
+#endif  
+
+  if (i <= clause_LastConstraintLitIndex(RuleClause)) {
+
+    /* Apply Sort Simplification for constraint literals only */
+    NegLits = list_List(term_Copy(Atom));
+    aux     = clause_Create(NegLits, list_Nil(), list_Nil(), Flags, Precedence);
+    clause_SetTemporary(aux);
+    list_Delete(NegLits);
+
+#ifdef CRW_DEBUG
+    clause_Print(aux);
+#endif
+    
+    NewClause = NULL;
+    OrigNum   = clause_Number(aux);
+    if (red_SortSimplification(prfs_DynamicSortTheory(Search), aux, NAT_MAX,
+			       DocProof, Flags, Precedence, &NewClause)) {
+      /* Sort Simplification was possible, so the unit clause was reduced */
+      /* to the empty clause. */
+
+      /* The splitting information is already set in <aux> or <NewClause>. */
+      if (DocProof)
+	/* If 'DocProof' is turned on, a copy was created and assigned */
+	/* to <NewClause>. */
+	red_CRwCalculateAdditionalParents(NewClause, list_Nil(), NULL, OrigNum);
+
+      if (NewClause != NULL) {
+	clause_Delete(aux);
+	return NewClause;
+      } else
+	return aux;
+    }
+    clause_Delete(aux);
+
+#ifdef CRW_DEBUG
+    printf("\n  Cons aux2 = ");
+#endif
+  }
+  
+  /* Collect literals for tautology test */
+  if (Negative) {
+    if (i <= clause_LastConstraintLitIndex(RuleClause))
+      NegLits = clause_CopyConstraint(RedClause);
+    else
+      NegLits = clause_CopyAntecedentExcept(RedClause, Except);
+    PosLits = list_List(term_Copy(Atom));
+  } else {
+    NegLits = list_List(term_Copy(Atom));
+    PosLits = clause_CopySuccedentExcept(RedClause, Except);
+  }
+  
+  /* Create clause for tautology test */
+  aux = clause_Create(list_Nil(), NegLits, PosLits, Flags, Precedence);
+  clause_SetTemporary(aux);
+  list_Delete(NegLits);
+  list_Delete(PosLits);
+  
+#ifdef CRW_DEBUG
+  clause_Print(aux);
+#endif
+
+  /* Apply special reduction. Propagate definitions x=t if for all literals  */
+  /* u=v (A=tt) of the resulting clause the conditions holds:                */
+  /* LeadingTerm > u{x->t} and LeadingTerm > v{x->t} (LeadingTerm > A{x->t}. */
+  if (red_PropagateDefinitions(aux, LeadingTerm, Flags, Precedence)) {
+#ifdef CRW_DEBUG
+    printf("\n  After propagation of definitions:\n  aux = ");
+    clause_Print(aux);
+#endif
+  }
+
+  /* Invoke forward reduction and tautology test */
+  NewClause     = NULL;
+  RedundantList = list_Nil();
+  OrigNum       = clause_Number(aux);
+  Redundant     = red_SelectedStaticReductions(Search, &aux, &NewClause,
+					       &RedundantList, Mode);
+  clause_SetTemporary(aux);
+  /* <aux> was possibly changed by some reductions, so mark it as */
+  /* temporary again. */
+  
+  /* Invoke tautology test if <aux> isn't redundant. */
+  if (Redundant || (!clause_IsEmptyClause(aux) && cc_Tautology(aux))) {
+
+    if (NewClause != NULL)
+      /* <aux> is subsumed by <NewClause> */
+      clause_UpdateSplitDataFromPartner(aux, NewClause);
+    
+    if (DocProof)
+      red_CRwCalculateAdditionalParents(aux, RedundantList, NewClause, OrigNum);
+  } else {
+    /* test failed */
+
+    clause_Delete(aux);
+    aux = NULL;
+  }
+  
+#ifdef CRW_DEBUG
+  if (aux != NULL) {
+    if (NewClause != NULL) {
+      printf("\n  Subsumer = ");
+      clause_Print(NewClause);
+    }
+    if (!list_Empty(RedundantList)) {
+      printf("\n  RedundantList: ");
+      clause_ListPrint(RedundantList);
+    }
+    
+    printf("\n  aux reduced = ");
+    clause_Print(aux);
+  } 
+  printf("\n  ----------");
+#endif
+  
+  /* Delete list of redundant clauses */
+  clause_DeleteClauseList(RedundantList);
+  
+  return aux;
+}
+
+
+static BOOL red_CRwTautologyCheck(PROOFSEARCH Search, CLAUSE RedClause, int i,
+				  TERM TermSInstance, CLAUSE RuleClause,
+				  int j, NAT Mode, CLAUSE *Result)
+/**************************************************************
+  INPUT:   A proof search object, two clauses, two literal indices
+           (one per clause), <TermSInstance> is a subterm of
+           literal <i> in <RedClause>, a mode defining the clause
+	   index used for intermediate reductions, and a pointer
+	   to a clause used as return value.
+  RETURNS: FALSE, if the clauses failed some tautology test or
+           the literal <i> in <RedClause> is not greater than literal
+	   <j> in <RedClause> with the substitution <sigma> applied.
+	   In this case <Result> is set to NULL.
+
+	   TRUE is returned if the clauses passed all tautology tests
+	   and literal <i> in <RedClause> is greater than literal <j>
+	   in <RuleClause> with the substitution <sigma> applied.
+	   In some cases <Result> is set to some auxiliary clause.
+	   This is done if some clauses from the index were used to
+	   reduce the intermediate clauses before the tautology test.
+	   The auxiliary clause is used to return the necessary splitting
+	   information for the current rewriting step.
+	   If the <DocProof> flag is true, the information about
+	   parent clauses is set in <Result>, too.
+  MEMORY:  Remember to delete the <Result> clause if it is not NULL.
+***************************************************************/
+{
+  FLAGSTORE  Flags, BackupFlags;
+  PRECEDENCE Precedence;
+  CLAUSE     RuleCopy, aux;
+  TERM       TermS;
+  int        last, h;
+  BOOL       Rewrite;
+
+#ifdef CHECK
+  if (!clause_LiteralIsOrientedEquality(clause_GetLiteral(RuleClause, j))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_CRwTautologyCheck:");
+    misc_ErrorReport(" literal %d in <RuleClause> %d", j,
+		     clause_Number(RuleClause));
+    misc_ErrorReport(" isn't an oriented equation");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Flags      = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+  *Result    = NULL;
+  
+  /* copy <RuleClause> and rename variables in copy */
+  RuleCopy = clause_Copy(RuleClause);
+  clause_RenameVarsBiggerThan(RuleCopy, clause_MaxVar(RedClause));
+  TermS = term_FirstArgument(clause_GetLiteralAtom(RuleCopy, j));
+
+  /* Remove parent information of copied clause and mark it as temporary */
+  list_Delete(clause_ParentClauses(RuleCopy));
+  clause_SetParentClauses(RuleCopy, list_Nil());
+  list_Delete(clause_ParentLiterals(RuleCopy));
+  clause_SetParentLiterals(RuleCopy, list_Nil());
+  clause_SetTemporary(RuleCopy);
+
+  /* establish bindings */
+  cont_StartBinding();
+  if (!unify_MatchBindings(cont_LeftContext(), TermS, TermSInstance)) {
+#ifdef CHECK
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_CRwTautologyCheck: terms aren't matchable");
+    misc_FinishErrorReport();
+#endif
+  }
+
+  /* Apply bindings to equation s=t, where s > t. Here the strict version */
+  /* of cont_Apply... can be applied, because all variables in s and t    */
+  /* are bound. */
+  cont_ApplyBindingsModuloMatching(cont_LeftContext(),
+				   clause_GetLiteralAtom(RuleCopy, j),
+				   TRUE);
+
+  /* Check whether E > (s=t)sigma. It suffices to check only positive */
+  /* equations. All other cases imply the condition. */
+  if (i >= clause_FirstSuccedentLitIndex(RedClause) &&
+      clause_LiteralIsEquality(clause_GetLiteral(RedClause, i)) &&
+      ord_LiteralCompare(clause_GetLiteralTerm(RedClause, i),
+			 clause_LiteralIsOrientedEquality(clause_GetLiteral(RedClause, i)),
+			 clause_GetLiteralTerm(RuleCopy, j), TRUE,
+			 FALSE, Flags, Precedence) != ord_GREATER_THAN) {
+    cont_BackTrack();
+    clause_Delete(RuleCopy);
+    return FALSE;
+  }
+
+  /*  if (subs_SubsumesBasic(RuleClause, RedClause, j, i)) {    Potential improvement, not completely
+    cont_BackTrack();                                           developed ....
+    return TRUE;
+    } else  */
+  {
+    int OldClauseCounter;
+    /* Apply bindings to the rest of <RuleCopy> */
+    last = clause_LastLitIndex(RuleCopy);
+    for (h = clause_FirstLitIndex(); h <= last; h++) {
+      if (h != j)
+	cont_ApplyBindingsModuloMatching(cont_LeftContext(),
+					 clause_GetLiteralAtom(RuleCopy, h),
+					 FALSE);
+    }
+    
+    /* Backtrack bindings before reduction rules are invoked */
+    cont_BackTrack();
+
+    /* Create new flag store and save current settings.  Must be improved ****     */
+    /* Then turn off flags for printing and contextual rewriting. */
+    /* IMPORTANT: the DocProof flag mustn't be changed!       */
+    BackupFlags = flag_CreateStore();
+    flag_TransferAllFlags(Flags, BackupFlags);
+#ifndef CRW_DEBUG
+    flag_ClearPrinting(Flags);
+#else
+    { /* HACK: turn on all printing flags for debugging */
+      FLAG_ID f;
+      
+      for (f = (FLAG_ID) 0; f < flag_MAXFLAG; f++) {
+	if (flag_IsPrinting(f))
+	  flag_SetFlagValue(Flags, f, flag_ON);
+      }
+    }
+#endif
+
+    /* ATTENTION: to apply CRw recursively, uncomment the following */
+    /* line and comment out the following two lines! */
+    /* flag_SetFlagValue(Flags, flag_RFCRW, flag_RFCRWON); */
+    flag_SetFlagValue(Flags, flag_RBCRW, flag_RBCRWOFF);
+    flag_SetFlagValue(Flags, flag_RFCRW, flag_RFCRWOFF);
+    
+    /* Examine all literals of <RuleCopy> except <j> */
+    Rewrite          = TRUE;
+    last             = clause_LastLitIndex(RuleCopy);
+    OldClauseCounter = clause_Counter();
+
+    for (h = clause_FirstLitIndex(); Rewrite && h <= last; h++) {
+      if (h != j) {
+	aux = red_CRwLitTautologyCheck(Search, RedClause, i, RuleCopy, h,
+				       TermSInstance, Mode);
+	if (aux == NULL)
+	  Rewrite = FALSE;
+	else {
+	  /* Store splitting data of <aux> in RuleCopy */
+	  clause_UpdateSplitDataFromPartner(RuleCopy, aux);
+	  /* Collect additonal parent information, if <DocProof> is turned on */
+	  if (flag_GetFlagValue(Flags, flag_DOCPROOF)) {
+	    clause_SetParentClauses(RuleCopy,
+				    list_Nconc(clause_ParentClauses(aux),
+					       clause_ParentClauses(RuleCopy)));
+	    clause_SetParentLiterals(RuleCopy,
+				     list_Nconc(clause_ParentLiterals(aux),
+						clause_ParentLiterals(RuleCopy)));
+	    clause_SetParentClauses(aux, list_Nil());
+	    clause_SetParentLiterals(aux, list_Nil());
+	  }
+	  clause_Delete(aux);
+	}
+      }
+    }
+    /* restore clause counter */
+    clause_SetCounter(OldClauseCounter);
+
+    /* reset flag store of proof search object and free backup store */
+    flag_TransferAllFlags(BackupFlags, Flags);
+    flag_DeleteStore(BackupFlags);
+  }
+
+  if (Rewrite)
+    *Result = RuleCopy;
+  else
+    /* cleanup */
+    clause_Delete(RuleCopy);
+
+  return Rewrite;
+}
+
+
+static void red_DocumentContextualRewriting(CLAUSE Clause, int i,
+					    CLAUSE RuleClause, int ri,
+					    LIST AdditionalPClauses,
+					    LIST AdditionalPLits)
+/**************************************************************
+  INPUT:   Two clauses and two literal indices (one per clause),
+           and two lists of additional parent clause numbers and
+	   parent literals.
+  RETURNS: Nothing.
+  EFFECT:  <Clause> is rewritten for the first time by
+           Contextual Rewriting. This function sets the parent
+           clause and parent literal information in <Clause>.
+	   <Clause> gets a new clause number.
+  CAUTION: The lists are not copied!
+***************************************************************/
+{
+#ifdef CHECK
+  if (list_Length(AdditionalPClauses) != list_Length(AdditionalPLits)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_DocumentContextualRewriting: lists of parent ");
+    misc_ErrorReport("clauses\n and literals have different length.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  list_Delete(clause_ParentClauses(Clause));
+  list_Delete(clause_ParentLiterals(Clause));
+  clause_SetParentClauses(Clause, AdditionalPClauses);
+  clause_SetParentLiterals(Clause, AdditionalPLits);
+  /* Add the old number of <Clause> as parent clause, */
+  /* before it gets a new clause number.              */
+  clause_AddParentClause(Clause, clause_Number(Clause));
+  clause_AddParentLiteral(Clause, i);
+  clause_AddParentClause(Clause, clause_Number(RuleClause));
+  clause_AddParentLiteral(Clause, ri);
+
+  clause_NewNumber(Clause);
+  clause_SetFromContextualRewriting(Clause);
+}
+
+
+static void red_DocumentFurtherCRw(CLAUSE Clause, int i, CLAUSE RuleClause,
+				   int ri, LIST AdditionalPClauses,
+				   LIST AdditionalPLits)
+/**************************************************************
+  INPUT:   Two clauses, two literal indices (one per clause),
+           and two lists of additional parent clause numbers and
+	   parent literal indices.
+  RETURNS: Nothing.
+  EFFECT:  <Clause> is a clause, that was rewritten before by
+           Contextual Rewriting. This function adds the parent
+           clause and parent literal information from one more
+           rewriting step to <Clause>. The information is added
+           to the front of the respective lists.
+  CAUTION: The lists are not copied!
+***************************************************************/
+{
+  int PClauseNum;
+
+#ifdef CHECK
+  if (list_Length(AdditionalPClauses) != list_Length(AdditionalPLits)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_DocumentFurtherCRw: lists of parent ");
+    misc_ErrorReport("clauses\n and literals have different length.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  PClauseNum = (int)list_Second(clause_ParentClauses(Clause));
+
+  clause_SetParentClauses(Clause, list_Nconc(AdditionalPClauses,
+					     clause_ParentClauses(Clause)));
+  clause_SetParentLiterals(Clause, list_Nconc(AdditionalPLits,
+					      clause_ParentLiterals(Clause)));
+
+  clause_AddParentClause(Clause, PClauseNum);
+  clause_AddParentLiteral(Clause, i);
+  clause_AddParentClause(Clause, clause_Number(RuleClause));
+  clause_AddParentLiteral(Clause, ri);
+}
+
+
+static BOOL red_ContextualRewriting(PROOFSEARCH Search, CLAUSE RedClause,
+				    NAT Mode, int Level, CLAUSE *Changed)
+/**************************************************************
+  INPUT:   A proof search object, a clause to reduce, the
+           reduction mode which defines the clause set used for
+	   reduction, a split level indicating the need of a copy
+	   if <Clause> is reduced by a clause of higher split level
+	   than <Level>, and a pointer to a clause used as return value.
+  RETURNS: TRUE, if contextual rewriting was possible, FALSE otherwise.
+           If rewriting was possible and the <DocProof> flag is true
+	   or the split level of the rewrite rule is higher than
+	   <Level>, a copy of <RedClause> that is rewritten wrt.
+	   the indexed clauses is returned in <*Changed>.
+	   Otherwise the clause is destructively rewritten and
+	   returned.
+  CAUTION: If rewriting wasn't applied, the value of <*Changed>
+           isn't set explicitely in this function.
+***************************************************************/
+{
+  TERM         RedAtom, RedTermS;
+  int          B_Stack;
+  int          ri, last;
+  BOOL         Rewritten, Result, Document;
+  TERM         TermS, PartnerEq;
+  LIST         Gen, EqScan, LitScan;
+  CLAUSE       Copy;
+  FLAGSTORE    Flags;
+  PRECEDENCE   Precedence;
+  SHARED_INDEX ShIndex;
+
+  Flags      = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+
+#ifdef CHECK
+  if (!clause_IsClause(RedClause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_ContextualRewriting: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(RedClause, Flags, Precedence);
+#endif
+  
+  /* Select clause index */
+  if (red_WorkedOffMode(Mode))
+    ShIndex = prfs_WorkedOffSharingIndex(Search);
+  else
+    ShIndex = prfs_UsableSharingIndex(Search);
+
+  last     = clause_LastSuccedentLitIndex(RedClause);
+  Document = flag_GetFlagValue(Flags, flag_DOCPROOF); 
+
+  Result = FALSE;
+  Copy   = RedClause;
+
+  /* Don't apply this rule on constraint literals! */
+  for (ri = clause_FirstAntecedentLitIndex(RedClause); ri <= last; ri++) {
+    if (!list_Empty(term_ArgumentList(clause_GetLiteralAtom(Copy, ri)))) {
+      Rewritten = TRUE;
+      while (Rewritten) {
+	Rewritten = FALSE;
+	RedAtom   = clause_GetLiteralAtom(Copy, ri);
+
+	B_Stack = stack_Bottom();
+	/* push subterms on stack except variables */
+	sharing_PushListReverseOnStack(term_ArgumentList(RedAtom));
+
+	while (!stack_Empty(B_Stack))  {
+	  RedTermS = (TERM)stack_PopResult();
+	  Gen = st_GetGen(cont_LeftContext(), sharing_Index(ShIndex), RedTermS);
+	  
+	  for ( ; !list_Empty(Gen) && !Rewritten; Gen = list_Pop(Gen)) {
+	    TermS = list_Car(Gen);
+	    
+	    /* A variable can't be greater than any other term, */
+	    /* so don't consider any variables here.            */
+	    if (!term_IsVariable(TermS)) {
+	      EqScan = term_SupertermList(TermS);
+	      
+	      for ( ; !list_Empty(EqScan) && !Rewritten;
+		    EqScan = list_Cdr(EqScan)) {
+		PartnerEq = list_Car(EqScan);
+		if (fol_IsEquality(PartnerEq) &&
+		    (term_FirstArgument(PartnerEq) == TermS)) {
+		  CLAUSE  RuleClause, HelpClause;
+		  LITERAL RuleLit;
+		  int     i;
+		  
+		  for (LitScan = sharing_NAtomDataList(PartnerEq); 
+		       !list_Empty(LitScan) && !Rewritten;
+		       LitScan = list_Cdr(LitScan)) {
+		    RuleLit    = list_Car(LitScan);
+		    RuleClause = clause_LiteralOwningClause(RuleLit);
+		    i         = clause_LiteralGetIndex(RuleLit);
+		    HelpClause = NULL;
+		    
+#ifdef CRW_DEBUG
+		    if (clause_LiteralIsPositive(RuleLit) &&
+			clause_LiteralGetFlag(RuleLit,STRICTMAXIMAL) &&
+			clause_LiteralIsOrientedEquality(RuleLit) &&
+			red_LeftTermOfEquationIsStrictlyMaximalTerm(RuleClause,
+								    RuleLit,
+								    Flags,
+								    Precedence)) {
+		      printf("\n------\nFCRw: %s\n%d  ", red_WorkedOffMode(Mode)
+			     ? "WorkedOff" : "Usable", i);
+		      clause_Print(RuleClause);
+		      printf("\n%d  ", ri);
+		      clause_Print(RedClause);
+		    }
+#endif
+
+		    if (clause_LiteralIsPositive(RuleLit) &&
+			clause_LiteralGetFlag(RuleLit,STRICTMAXIMAL) &&
+			clause_LiteralIsOrientedEquality(RuleLit) &&
+			red_LeftTermOfEquationIsStrictlyMaximalTerm(RuleClause,
+								    RuleLit,
+								    Flags,
+								    Precedence) &&
+			red_CRwTautologyCheck(Search, Copy, ri, RedTermS,
+					      RuleClause, i, Mode,
+					      &HelpClause)) {
+		      TERM   TermT;
+		      
+		      if (RedClause == Copy &&
+			  (Document || 
+			   prfs_SplitLevelCondition(clause_SplitLevel(RuleClause),
+						    clause_SplitLevel(RedClause),Level) ||
+			   prfs_SplitLevelCondition(clause_SplitLevel(HelpClause),
+						    clause_SplitLevel(RedClause),
+						    Level))) {
+			Copy    = clause_Copy(RedClause);
+			RedAtom = clause_GetLiteralAtom(Copy, ri);
+		      }
+		      
+		      if (!Result && flag_GetFlagValue(Flags, flag_PCRW)) {
+			/* Clause is rewitten for the first time and */
+			/* printing is turned on. */
+			fputs("\nFContRewriting: ", stdout);
+			clause_Print(Copy);
+			fputs(" ==>[ ", stdout);
+		      }
+		      
+		      if (Document) {
+			LIST PClauses, PLits;
+
+			/* Get additional parent information from */
+			/* <HelpClause> */
+			PClauses = PLits = list_Nil();
+			if (HelpClause != NULL) {
+			  PClauses = clause_ParentClauses(HelpClause);
+			  PLits    = clause_ParentLiterals(HelpClause);
+			  clause_SetParentClauses(HelpClause, list_Nil());
+			  clause_SetParentLiterals(HelpClause, list_Nil());
+			} else
+			  PClauses = PLits = list_Nil();
+
+			if (!Result)
+			  red_DocumentContextualRewriting(Copy, ri,
+							  RuleClause, i,
+							  PClauses, PLits);
+			else
+			  red_DocumentFurtherCRw(Copy, ri, RuleClause, i,
+						 PClauses, PLits);
+		      }
+		      Result = TRUE;
+		      
+		      cont_StartBinding();
+		      unify_MatchBindings(cont_LeftContext(), TermS, RedTermS);
+		      TermT = cont_ApplyBindingsModuloMatching(cont_LeftContext(),
+							       term_Copy(term_SecondArgument(PartnerEq)),
+							       TRUE);
+		      cont_BackTrack();
+		      
+		      term_ReplaceSubtermBy(RedAtom, RedTermS, TermT);
+		      Rewritten = TRUE;
+		      /* Set splitting data from parents */
+		      clause_UpdateSplitDataFromPartner(Copy, RuleClause);
+		      if (HelpClause != NULL) {
+			/* Store splitting data from intermediate clauses */
+			clause_UpdateSplitDataFromPartner(Copy, HelpClause);
+			clause_Delete(HelpClause);
+		      }
+		      term_Delete(TermT);
+		      stack_SetBottom(B_Stack);
+		      
+		      if (flag_GetFlagValue(Flags, flag_PCRW))
+			printf("%d.%d ",clause_Number(RuleClause), i);
+		      clause_UpdateWeight(Copy, Flags);
+		    }
+		  }
+		}
+	      }
+	    }
+	  }
+	  list_Delete(Gen);
+	}
+      }
+    }
+  }
+  if (Result) {
+    clause_OrientAndReInit(Copy, Flags, Precedence);
+    if (flag_GetFlagValue(Flags, flag_PCRW)) {
+      fputs("] ", stdout);
+      clause_Print(Copy);
+    }
+    if (Copy != RedClause) {
+      clause_OrientAndReInit(RedClause, Flags, Precedence);
+      *Changed = Copy;
+    }
+  }
+
+#ifdef CHECK
+  if (Copy != RedClause)
+    clause_Check(Copy, Flags, Precedence);
+  clause_Check(RedClause, Flags, Precedence);
+#endif
+
+  return Result;
+}
+
+
+static LIST red_BackSubsumption(CLAUSE RedCl, SHARED_INDEX ShIndex,
+				FLAGSTORE Flags, PRECEDENCE Precedence)
+/**********************************************************
+  INPUT:   A pointer to a non-empty clause, an index of 
+           clauses, a flag store and a precedence.
+  RETURNS: The list of clauses that are subsumed by the 
+           clause RedCl.
+***********************************************************/
+{
+  TERM    Atom,CandTerm;
+  CLAUSE  SubsumedCl;
+  LITERAL CandLit;
+  LIST    CandLits, Scan, SubsumedList;
+  int     i, j, lc, fa, la, fs, l;
+  
+#ifdef CHECK
+  if (!clause_IsClause(RedCl, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_BackSubsumption :");
+    misc_ErrorReport(" Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(RedCl, Flags, Precedence);
+#endif
+  
+  /* Special case: clause is empty */
+  if (clause_IsEmptyClause(RedCl))
+    return list_Nil();
+
+  SubsumedList = list_Nil();
+  
+  lc = clause_LastConstraintLitIndex(RedCl);
+  fa = clause_FirstAntecedentLitIndex(RedCl);
+  la = clause_LastAntecedentLitIndex(RedCl);
+  fs = clause_FirstSuccedentLitIndex(RedCl);
+  l  = clause_LastLitIndex(RedCl);
+    
+  /* Choose the literal with the greatest weight to start the search */
+  i          = clause_FirstLitIndex();
+  for (j = i + 1; j <= l; j++) {
+    if (clause_LiteralWeight(clause_GetLiteral(RedCl, j)) >
+	clause_LiteralWeight(clause_GetLiteral(RedCl, i)))
+      i = j;
+  }
+  
+  Atom       = clause_GetLiteralAtom(RedCl, i);
+  CandTerm   = st_ExistInstance(cont_LeftContext(), sharing_Index(ShIndex), Atom);
+    
+  while (CandTerm) {
+    CandLits = sharing_NAtomDataList(CandTerm);
+      
+    for (Scan = CandLits; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+      CandLit    = list_Car(Scan);
+      SubsumedCl = clause_LiteralOwningClause(CandLit);
+      j          = clause_LiteralGetIndex(CandLit);
+	
+      if (RedCl != SubsumedCl &&
+	  /* Literals must be from same part of the clause */
+	  ((i<=lc && clause_LiteralIsFromConstraint(CandLit)) ||
+	   (i>=fa && i<=la && clause_LiteralIsFromAntecedent(CandLit)) ||
+	   (i>=fs && clause_LiteralIsFromSuccedent(CandLit))) &&
+	  !list_PointerMember(SubsumedList, SubsumedCl) &&
+	  subs_SubsumesBasic(RedCl, SubsumedCl, i, j))
+	SubsumedList = list_Cons(SubsumedCl, SubsumedList);
+    }
+      
+    CandTerm = st_NextCandidate();
+  }
+    
+  if (fol_IsEquality(Atom) && 
+      clause_LiteralIsNotOrientedEquality(clause_GetLiteral(RedCl, i))) {
+    Atom      = term_Create(fol_Equality(),
+			    list_Reverse(term_ArgumentList(Atom)));
+    CandTerm  = st_ExistInstance(cont_LeftContext(), sharing_Index(ShIndex), Atom);
+      
+    while (CandTerm) {
+      CandLits = sharing_NAtomDataList(CandTerm);
+	
+      for (Scan = CandLits; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+	CandLit    = list_Car(Scan);
+	SubsumedCl = clause_LiteralOwningClause(list_Car(Scan));
+	/* if (!clause_GetFlag(SubsumedCl, BLOCKED)) { */
+	j          = clause_LiteralGetIndex(list_Car(Scan));
+	  
+	if ((RedCl != SubsumedCl) && 
+	    /* Literals must be from same part of the clause */
+	    ((i<=lc && clause_LiteralIsFromConstraint(CandLit)) ||
+	     (i>=fa && i<=la && clause_LiteralIsFromAntecedent(CandLit)) ||
+	     (i>=fs && clause_LiteralIsFromSuccedent(CandLit))) &&
+	    !list_PointerMember(SubsumedList, SubsumedCl) &&
+	    subs_SubsumesBasic(RedCl, SubsumedCl, i, j))
+	  SubsumedList = list_Cons(SubsumedCl, SubsumedList);
+	/* } */
+      }
+	
+      CandTerm = st_NextCandidate();
+    }
+      
+    list_Delete(term_ArgumentList(Atom));
+    term_Free(Atom);
+  }
+      
+  if (flag_GetFlagValue(Flags, flag_PSUB)) {
+    for (Scan = SubsumedList; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+      SubsumedCl = list_Car(Scan);
+      fputs("\nBSubsumption: ", stdout);
+      clause_Print(SubsumedCl);
+      printf(" by %d ",clause_Number(RedCl));
+    }
+  }
+  return SubsumedList;
+}
+
+
+static LIST red_GetBackMRResLits(CLAUSE Clause, LITERAL ActLit, SHARED_INDEX ShIndex)
+/**************************************************************
+  INPUT:   A clause, one of its literals and an Index.
+  RETURNS: A list of clauses with a complementary literal instance 
+           that are subsumed if these literals are ignored.
+	   the empty list if no such clause exists.
+  MEMORY:  Allocates the needed listnodes.
+***************************************************************/
+{
+  CLAUSE  PClause;
+  LITERAL PLit;
+  LIST    LitScan, PClLits;
+  TERM    CandTerm;
+  int     i;
+
+  PClLits   = list_Nil();
+  i         = clause_LiteralGetIndex(ActLit);
+
+  CandTerm  = st_ExistInstance(cont_LeftContext(),
+			       sharing_Index(ShIndex),
+			       clause_LiteralAtom(ActLit));
+
+  while (CandTerm) {
+
+    LitScan = sharing_NAtomDataList(CandTerm); /* CAUTION ! */
+
+    for ( ; !list_Empty(LitScan); LitScan = list_Cdr(LitScan)) {
+
+      PLit    = list_Car(LitScan);
+      PClause = clause_LiteralOwningClause(PLit);
+
+      if (PClause != Clause &&
+	  clause_LiteralsAreComplementary(ActLit,PLit) &&
+	  subs_SubsumesBasic(Clause,PClause,i,clause_LiteralGetIndex(PLit)))
+	PClLits = list_Cons(PLit, PClLits);
+    }
+    
+    CandTerm = st_NextCandidate();
+  }
+  return PClLits;
+}
+
+
+static LIST red_BackMatchingReplacementResolution(CLAUSE RedClause, SHARED_INDEX ShIndex,
+						  FLAGSTORE Flags, PRECEDENCE Precedence,
+						  LIST* Result)
+/**************************************************************
+  INPUT:   A clause, a shared index, a flag store, a 
+           precedence, and a pointer to a result list.
+  RETURNS: The return value itself contains a list of clauses 
+           from <ShIndex> that is reducible by <RedClause> via 
+	   clause reduction.
+	   The return value stored in <*Result> contains the 
+	   result of this operation.
+	   If the <DocProof> flag is true then the clauses in 
+	   <*Result> contain information about the reduction.
+***************************************************************/
+{
+  LIST   Blocked;
+  CLAUSE Copy;
+  BOOL   Document;
+
+#ifdef CHECK
+  if (!clause_IsClause(RedClause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_BackMatchingReplacementResolution:");
+    misc_ErrorReport(" Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(RedClause, Flags, Precedence);
+#endif
+
+  Blocked = list_Nil();
+  Document = flag_GetFlagValue(Flags, flag_DOCPROOF);
+
+  if (clause_Length(RedClause) == 1) {
+    LITERAL ActLit, PLit;
+    LIST    LitList, Scan, Iter;
+    TERM    CandTerm;
+    int     RedClNum;
+    
+    ActLit      = clause_GetLiteral(RedClause, clause_FirstLitIndex());
+
+    if (!fol_IsEquality(clause_LiteralAtom(ActLit)) ||  /* Reduce with negative equations too */
+	clause_LiteralIsNegative(ActLit)) {
+      CLAUSE PClause;
+      LIST   PIndL;
+
+      CandTerm = st_ExistInstance(cont_LeftContext(), sharing_Index(ShIndex), clause_LiteralAtom(ActLit));
+      RedClNum = clause_Number(RedClause);
+      LitList  = list_Nil();
+
+      while (CandTerm) {
+	for (Iter = sharing_NAtomDataList(CandTerm); !list_Empty(Iter); Iter = list_Cdr(Iter))
+	  if (clause_LiteralsAreComplementary(ActLit,list_Car(Iter)))
+	    LitList = list_Cons(list_Car(Iter),LitList);
+	CandTerm = st_NextCandidate();
+      }
+
+      /* It is important to get all literals first,
+	 because there may be several literals in the same clause which can be reduced by <ActLit> */
+      
+      while (!list_Empty(LitList)) {
+	PLit    = list_Car(LitList);
+	PIndL   = list_List(PLit);
+	PClause = clause_LiteralOwningClause(PLit);
+	Blocked = list_Cons(PClause, Blocked);
+
+	if (flag_GetFlagValue(Flags, flag_PMRR)) {
+	  fputs("\nBMatchingReplacementResolution: ", stdout);
+	  clause_Print(PClause);
+	  printf(" ==>[ %d.%d ] ",clause_Number(RedClause),clause_FirstLitIndex());
+	}
+
+	Iter = LitList;
+	for (Scan=list_Cdr(LitList);!list_Empty(Scan);Scan=list_Cdr(Scan)) /* Get brothers of PLit */
+	  if (PClause == clause_LiteralOwningClause(list_Car(Scan))) {
+	    list_Rplacd(Iter,list_Cdr(Scan));
+	    list_Rplacd(Scan,PIndL);
+	    PIndL = Scan;
+	    Scan  = Iter;
+	  }
+	  else
+	    Iter = Scan;
+	Iter    = LitList;
+	LitList = list_Cdr(LitList);
+	list_Free(Iter);
+	Copy    = clause_Copy(PClause);
+	clause_RemoveFlag(Copy,WORKEDOFF);
+	clause_UpdateSplitDataFromPartner(Copy, RedClause);
+	for(Scan=PIndL;!list_Empty(Scan);Scan=list_Cdr(Scan))       /* Change lits to indexes */
+	  list_Rplaca(Scan,(POINTER)clause_LiteralGetIndex(list_Car(Scan)));
+	clause_DeleteLiterals(Copy, PIndL, Flags, Precedence);
+	
+	if (Document)
+	  /* Lists are consumed */
+	  red_DocumentMatchingReplacementResolution(Copy, PIndL, list_List((POINTER)RedClNum),
+						    list_List((POINTER)clause_FirstLitIndex()));
+
+	else
+	  list_Delete(PIndL);	
+	
+	if (flag_GetFlagValue(Flags, flag_PMRR))
+	  clause_Print(Copy);
+	*Result = list_Cons(Copy, *Result);
+      }
+    }
+    return Blocked;
+  } 
+  else {
+    CLAUSE  PClause;
+    LITERAL ActLit, PLit;
+    LIST    LitScan,LitList;
+    int     i,length,RedClNum,PInd;
+
+    RedClNum    = clause_Number(RedClause);
+    length      = clause_Length(RedClause);
+
+    for (i = clause_FirstLitIndex(); i < length; i++) {
+      ActLit = clause_GetLiteral(RedClause, i);
+      
+      if (!fol_IsEquality(clause_LiteralAtom(ActLit))) {
+	LitList = red_GetBackMRResLits(RedClause, ActLit, ShIndex);
+	
+	for (LitScan = LitList;!list_Empty(LitScan);LitScan = list_Cdr(LitScan)) {
+	  PLit    = list_Car(LitScan);
+	  PClause = clause_LiteralOwningClause(PLit);
+	  PInd    = clause_LiteralGetIndex(PLit);
+	  Copy    = clause_Copy(PClause);
+	  if (list_PointerMember(Blocked,PClause)) {
+	    if (!flag_GetFlagValue(Flags, flag_DOCPROOF))
+	      clause_NewNumber(Copy);
+	  }
+	  else
+	    Blocked = list_Cons(PClause, Blocked);
+	  clause_RemoveFlag(Copy,WORKEDOFF);
+	  clause_UpdateSplitDataFromPartner(Copy, RedClause);
+	  clause_DeleteLiteral(Copy, PInd, Flags, Precedence);
+
+	  if (Document)
+	    red_DocumentMatchingReplacementResolution(Copy, list_List((POINTER)PInd), 
+						      list_List((POINTER)RedClNum), 
+						      list_List((POINTER)i));
+	  
+	  if (flag_GetFlagValue(Flags, flag_PMRR)) {
+	    fputs("\nBMatchingReplacementResolution: ", stdout);
+	    clause_Print(PClause);
+	    printf(" ==>[ %d.%d ] ",clause_Number(RedClause),i);
+	    clause_Print(Copy);
+	  }
+	  *Result = list_Cons(Copy, *Result);
+	}
+	list_Delete(LitList);
+      }
+    }
+    return Blocked;
+  }
+}
+
+
+static void red_ApplyRewriting(CLAUSE RuleCl, int ri, CLAUSE PartnerClause,
+			       int pli, TERM PartnerTermS, FLAGSTORE Flags,
+			       PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause to use for rewriting, the index of a 
+           positive equality literal where the first equality
+	   argument is greater, a clause, the index of a
+	   literal with subterm <PartnerTermS> that can be
+	   rewritten, a flag store and a precedence.
+  RETURNS: Nothing.
+  EFFECT:  The atom of literal pli in PartnerClause is
+           destructively changed !!!
+	   The <DocProof> flag is considered.
+***************************************************************/
+{
+  LITERAL PartnerLit;
+  TERM    ReplaceTermT, NewAtom;
+
+#ifdef CHECK
+  clause_Check(PartnerClause, Flags, Precedence);
+  clause_Check(RuleCl, Flags, Precedence);
+#endif
+
+  if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+    red_DocumentRewriting(PartnerClause, pli, RuleCl, ri);
+
+  if (flag_GetFlagValue(Flags, flag_PREW)) {
+    fputs("\nBRewriting: ", stdout);
+    clause_Print(PartnerClause);
+    printf(" ==>[ %d.%d ] ", clause_Number(RuleCl), ri); 
+  }
+
+  PartnerLit = clause_GetLiteral(PartnerClause, pli);
+
+  ReplaceTermT =
+    cont_ApplyBindingsModuloMatchingReverse(cont_LeftContext(),
+			     term_Copy(term_SecondArgument(clause_GetLiteralTerm(RuleCl, ri))));
+  
+  NewAtom = clause_LiteralSignedAtom(PartnerLit);
+  term_ReplaceSubtermBy(NewAtom, PartnerTermS, ReplaceTermT);
+  term_Delete(ReplaceTermT);
+
+  clause_OrientAndReInit(PartnerClause, Flags, Precedence);
+  clause_UpdateSplitDataFromPartner(PartnerClause, RuleCl);
+
+  if (flag_GetFlagValue(Flags, flag_PREW))
+    clause_Print(PartnerClause);
+}
+
+
+static LIST red_LiteralRewriting(CLAUSE RedClause, LITERAL ActLit, int ri,
+				 SHARED_INDEX ShIndex, FLAGSTORE Flags,
+				 PRECEDENCE Precedence, LIST* Result)
+/**************************************************************
+  INPUT:   A clause, a positive equality literal where the
+           first equality argument is greater, its index, an 
+	   index of clauses, a flag store, a precedence and a
+	   pointer to a list of clauses that were rewritten.
+  RETURNS: The list of clauses from the index that can be 
+           rewritten by <ActLit> and <RedClause>.
+           The rewritten clauses are stored in <*Result>.
+  EFFECT:  The <DocProof> flag is considered.
+***************************************************************/
+{
+  TERM TermS, CandTerm;
+  LIST Blocked;
+
+#ifdef CHECK
+  if (!clause_LiteralIsLiteral(ActLit) || !clause_LiteralIsEquality(ActLit) ||
+      !clause_LiteralIsOrientedEquality(ActLit)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_LiteralRewriting: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(RedClause, Flags, Precedence);
+#endif
+
+  Blocked    = list_Nil();
+  TermS      = term_FirstArgument(clause_LiteralSignedAtom(ActLit));  /* Vars can't be greater ! */
+
+  CandTerm = st_ExistInstance(cont_LeftContext(), sharing_Index(ShIndex), TermS);
+
+  while (CandTerm) {
+
+    if (!term_IsVariable(CandTerm) &&
+	!symbol_IsPredicate(term_TopSymbol(CandTerm))) {
+      LIST LitList;
+      
+      LitList = sharing_GetDataList(CandTerm, ShIndex);
+
+      for ( ; !list_Empty(LitList); LitList = list_Pop(LitList)){
+	LITERAL PartnerLit;
+	CLAUSE  PartnerClause;
+	int     pli;
+
+	PartnerLit    = list_Car(LitList);
+	pli           = clause_LiteralGetIndex(PartnerLit);
+	PartnerClause = clause_LiteralOwningClause(PartnerLit);
+
+	/* Partner literal must be from antecedent or succedent */
+	if (clause_Number(RedClause) != clause_Number(PartnerClause) &&
+	    pli >= clause_FirstAntecedentLitIndex(PartnerClause) &&
+	    !list_PointerMember(Blocked, PartnerClause) &&
+	    subs_SubsumesBasic(RedClause, PartnerClause, ri, pli)) {
+	  CLAUSE Copy;
+
+	  Blocked = list_Cons(PartnerClause, Blocked);
+	  Copy    = clause_Copy(PartnerClause);
+	  clause_RemoveFlag(Copy, WORKEDOFF);
+	  red_ApplyRewriting(RedClause, ri, Copy, pli, CandTerm,
+			     Flags, Precedence);
+	  *Result = list_Cons(Copy, *Result);
+	}
+      }
+    }
+    CandTerm = st_NextCandidate();
+  }
+  return Blocked;
+}
+
+
+static LIST red_BackRewriting(CLAUSE RedClause, SHARED_INDEX ShIndex,
+			      FLAGSTORE Flags, PRECEDENCE Precedence,
+			      LIST* Result)
+/**************************************************************
+  INPUT:   A clause, and Index, a flag store, a precedence and
+           a pointer to the list of rewritten clauses.
+  RETURNS: A list of clauses that can be rewritten with
+           <RedClause> and the result of this operation is
+	   stored in <*Result>.
+  EFFECT:  The <DocProof> flag is considered.
+***************************************************************/
+{
+  int     i,length;
+  LITERAL ActLit;
+  LIST    Blocked;
+
+#ifdef CHECK
+  if (!(clause_IsClause(RedClause, Flags, Precedence))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_BackRewriting :");
+    misc_ErrorReport(" Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(RedClause, Flags, Precedence);
+#endif
+  
+  Blocked = list_Nil();
+  length  = clause_Length(RedClause);
+  
+  for (i=clause_FirstSuccedentLitIndex(RedClause); i < length; i++) {
+    ActLit = clause_GetLiteral(RedClause, i);
+    if (clause_LiteralIsOrientedEquality(ActLit)) {
+      Blocked = list_Nconc(red_LiteralRewriting(RedClause, ActLit, i,
+						ShIndex, Flags, Precedence,
+						Result),
+			   Blocked);
+    }
+      
+#ifdef CHECK
+    if (fol_IsEquality(clause_LiteralSignedAtom(ActLit))) {
+      ord_RESULT HelpRes;
+      
+      HelpRes =
+	ord_Compare(term_FirstArgument(clause_LiteralSignedAtom(ActLit)), 
+		    term_SecondArgument(clause_LiteralSignedAtom(ActLit)),
+		    Flags, Precedence);
+	
+      if (ord_IsSmallerThan(HelpRes)){ /* For Debugging */
+	misc_StartErrorReport();
+	misc_ErrorReport("\n In red_BackRewriting:");
+	misc_ErrorReport("First Argument smaller than second in RedClause.\n");
+	misc_FinishErrorReport();
+      }
+    } /* end of if (fol_IsEquality). */
+#endif
+  } /* end of for 'all succedent literals'. */
+  Blocked = list_PointerDeleteDuplicates(Blocked);
+  return Blocked;
+}
+
+
+/**************************************************************/
+/* BACKWARD CONTEXTUAL REWRITING                              */
+/**************************************************************/
+
+static LIST red_BackCRwOnLiteral(PROOFSEARCH Search, CLAUSE RuleClause,
+				 LITERAL Lit, int i, NAT Mode, LIST* Result)
+/**************************************************************
+  INPUT:   A proof search object, a clause that is used to rewrite
+           other clauses, a positive literal from the clause,
+	   that is a strictly maximal, oriented equation, the index
+	   of the literal, a mode defining which clause index
+	   is used to find rewritable clauses, and a pointer
+           to a list that is used as return value.
+	   The left term of the equation has to be the strictly
+	   maximal term in the clause, i.e. it is bigger than
+	   any other term.
+  RETURNS: The list of clauses from the clause index that can be
+           rewritten by <Lit> and <RuleClause>.
+           The rewritten clauses are stored in <*Result>.
+  EFFECT:  The <DocProof> flag is considered.
+***************************************************************/
+{
+  TERM         TermS, CandTerm, ReplaceTermT;
+  LIST         Inst, Blocked;
+  FLAGSTORE    Flags;
+  PRECEDENCE   Precedence;
+  SHARED_INDEX ShIndex;
+
+  Flags      = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+  if (red_WorkedOffMode(Mode))
+    ShIndex = prfs_WorkedOffSharingIndex(Search);
+  else
+    ShIndex = prfs_UsableSharingIndex(Search);
+
+#ifdef CHECK
+  if (!clause_LiteralIsLiteral(Lit) || !clause_LiteralIsEquality(Lit) ||
+      !clause_LiteralGetFlag(Lit, STRICTMAXIMAL) ||
+      !clause_LiteralIsOrientedEquality(Lit)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_BackCRwOnLiteral: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(RuleClause, Flags, Precedence);
+#endif
+
+  Blocked = list_Nil();
+  TermS   = term_FirstArgument(clause_LiteralSignedAtom(Lit));
+
+  /* Get all instances of <TermS> at once. This can't be done iteratively */
+  /* since other reduction rules are invoked within the following loop. */
+  Inst = st_GetInstance(cont_LeftContext(), sharing_Index(ShIndex), TermS);
+
+  for ( ; !list_Empty(Inst); Inst = list_Pop(Inst)) {
+    CandTerm = list_Car(Inst);
+    
+    if (!term_IsVariable(CandTerm) &&
+	!symbol_IsPredicate(term_TopSymbol(CandTerm))) {
+      LIST LitList;
+      
+      LitList = sharing_GetDataList(CandTerm, ShIndex);
+      
+      for ( ; !list_Empty(LitList); LitList = list_Pop(LitList)){
+	LITERAL RedLit;
+	CLAUSE  RedClause, HelpClause;
+	int     ri;
+	
+	RedLit     = list_Car(LitList);
+	ri         = clause_LiteralGetIndex(RedLit);
+	RedClause  = clause_LiteralOwningClause(RedLit);
+	HelpClause = NULL;
+	
+#ifdef CRW_DEBUG
+	if (clause_Number(RuleClause) != clause_Number(RedClause) &&
+	    ri >= clause_FirstAntecedentLitIndex(RedClause) &&
+	    !list_PointerMember(Blocked, RedClause)) {
+	  printf("\n------\nBCRw: %s\n%d  ", red_WorkedOffMode(Mode) ?
+		 "WorkedOff" : "Usable", i);
+	  clause_Print(RuleClause);
+	  printf("\n%d  ", ri);
+	  clause_Print(RedClause);
+	}
+#endif
+
+	/* Partner literal must be from antecedent or succedent */
+	if (clause_Number(RuleClause) != clause_Number(RedClause) &&
+	    ri >= clause_FirstAntecedentLitIndex(RedClause) &&
+	    /* Check that clause wasn't already rewritten by this literal.   */
+	    /* Necessary because then the old version of the clause is still */
+	    /* in the index, but the rewritten version in not in the index.  */
+	    !list_PointerMember(Blocked, RedClause) &&
+	    red_CRwTautologyCheck(Search, RedClause, ri, CandTerm,
+				  RuleClause, i, Mode, &HelpClause)) {
+	  CLAUSE Copy;
+	  
+	  /* The <PartnerClause> has to be copied because it's indexed. */
+	  Blocked = list_Cons(RedClause, Blocked);
+	  Copy    = clause_Copy(RedClause);
+	  clause_RemoveFlag(Copy, WORKEDOFF);
+	 	  	  
+	  /* Establish bindings */
+	  cont_StartBinding();
+	  if (!unify_MatchBindings(cont_LeftContext(), TermS, CandTerm)) {
+#ifdef CHECK
+	    misc_StartErrorReport();
+	    misc_ErrorReport("\n In red_BackCRwOnLiteral: terms aren't ");
+	    misc_ErrorReport("matchable.");
+	    misc_FinishErrorReport();
+#endif
+	  }
+	  /* The variable check in cont_ApplyBindings... is turned on here */
+	  /* because all variables is s are bound, and s > t. So all       */
+	  /* variables in t are bound, too. */
+	  ReplaceTermT =
+	    cont_ApplyBindingsModuloMatching(cont_LeftContext(),
+					     term_Copy(term_SecondArgument(clause_GetLiteralTerm(RuleClause, i))),
+					     TRUE);
+	  cont_BackTrack();
+
+	  /* Modify copied clause */
+	  term_ReplaceSubtermBy(clause_GetLiteralAtom(Copy, ri), CandTerm,
+				ReplaceTermT);
+	  term_Delete(ReplaceTermT);
+	  
+	  /* Proof documentation */
+	  if (flag_GetFlagValue(Flags, flag_DOCPROOF)) {
+	    LIST PClauses, PLits;
+
+	    if (HelpClause != NULL) {
+	      /* Get additional parent clauses and literals from the */
+	      /* tautology check. */
+	      PClauses = clause_ParentClauses(HelpClause);
+	      PLits    = clause_ParentLiterals(HelpClause);
+	      clause_SetParentClauses(HelpClause, list_Nil());
+	      clause_SetParentLiterals(HelpClause, list_Nil());
+	    } else
+	      PClauses = PLits = list_Nil();
+	    
+	    red_DocumentContextualRewriting(Copy, ri, RuleClause, i,
+					    PClauses, PLits);
+	  }
+
+	  /* Set splitting data according to all parents */
+	  clause_UpdateSplitDataFromPartner(Copy, RuleClause);
+	  if (HelpClause != NULL) {
+	    clause_UpdateSplitDataFromPartner(Copy, HelpClause);
+	    clause_Delete(HelpClause);
+	  }
+
+	  clause_OrientAndReInit(Copy, Flags, Precedence);
+	  
+	  if (flag_GetFlagValue(Flags, flag_PCRW)) {
+	    fputs("\nBContRewriting: ", stdout);
+	    clause_Print(RedClause);
+	    printf(" ==>[ %d.%d ] ", clause_Number(RuleClause), i);
+	    clause_Print(Copy);
+	  }
+	  	  
+	  *Result = list_Cons(Copy, *Result);
+	}
+      }
+    }
+  }
+
+  return Blocked;
+}
+
+
+static LIST red_BackContextualRewriting(PROOFSEARCH Search, CLAUSE RuleClause,
+					NAT Mode, LIST* Result)
+/**************************************************************
+  INPUT:   A proof search object, a clause that is used to rewrite
+           other clauses, a mode flag that indicates which clause
+           index is used to find rewritable clauses, and a pointer
+           to a list that is used as return value.
+  RETURNS: A list of clauses that can be reduced
+           with Contextual Rewriting with <RuleClause>.
+           The clauses resulting from the rewriting steps are
+	   stored in <*Result>.
+  EFFECT:  The <DocProof> flag is considered. Every rewritable clause
+           is copied before rewriting is applied! This has to be done,
+	   because the rewritable clauses are indexed.
+***************************************************************/
+{
+  BOOL       found;
+  int        i, ls;
+  LITERAL    Lit;
+  LIST       Blocked;
+  FLAGSTORE  Flags;
+  PRECEDENCE Precedence;
+
+  Flags      = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+
+#ifdef CHECK
+  if (!clause_IsClause(RuleClause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_BackContextualRewriting: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(RuleClause, Flags, Precedence);
+#endif
+  
+  Blocked = list_Nil();
+  ls      = clause_LastSuccedentLitIndex(RuleClause);
+  found   = FALSE;
+
+  for (i = clause_FirstSuccedentLitIndex(RuleClause); i <= ls && !found; i++) {
+    Lit = clause_GetLiteral(RuleClause, i);
+    if (clause_LiteralIsOrientedEquality(Lit) &&
+	clause_LiteralGetFlag(Lit, STRICTMAXIMAL) &&
+	red_LeftTermOfEquationIsStrictlyMaximalTerm(RuleClause, Lit, Flags,
+						    Precedence)) {
+      Blocked = list_Nconc(red_BackCRwOnLiteral(Search, RuleClause, Lit, i,
+						Mode, Result),
+			   Blocked);
+      /* Stop loop: there's only one strictly maximal term per clause */
+      found = TRUE;
+    }
+  }
+
+  Blocked = list_PointerDeleteDuplicates(Blocked);
+  return Blocked;
+}
+
+
+static void red_DocumentSortSimplification(CLAUSE Clause, LIST Indexes,
+					   LIST Clauses)
+/*********************************************************
+  INPUT:   A clause and the literal indices and clauses
+           involved in sort simplification.
+  RETURNS: Nothing.
+  MEMORY:  Consumes the input lists.
+**********************************************************/
+{
+  LIST Scan,Declarations,Self;
+
+  Declarations = list_Nil();
+  Self         = list_Nil();
+
+  list_Delete(clause_ParentClauses(Clause));
+  list_Delete(clause_ParentLiterals(Clause));  
+  
+  for(Scan=Indexes;!list_Empty(Scan);Scan=list_Cdr(Scan))
+    Self = list_Cons((POINTER)clause_Number(Clause),Self);
+  
+  for(Scan=Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Declarations = list_Cons((POINTER)clause_FirstSuccedentLitIndex(list_Car(Scan)),Declarations);
+    list_Rplaca(Scan,(POINTER)clause_Number(list_Car(Scan)));
+  }
+
+  clause_SetParentLiterals(Clause, list_Nconc(Indexes,Declarations));
+  clause_SetParentClauses(Clause, list_Nconc(Self,Clauses));
+
+  clause_SetNumber(Clause, clause_IncreaseCounter());
+  clause_SetFromSortSimplification(Clause);
+}
+
+
+static BOOL red_SortSimplification(SORTTHEORY Theory, CLAUSE Clause, NAT Level,
+				   BOOL Document, FLAGSTORE Flags,
+				   PRECEDENCE Precedence, CLAUSE *Changed)
+/**********************************************************
+  INPUT:   A sort theory, a clause, the last backtrack
+           level of the current proof search, a boolean
+	   flag concerning proof documentation, a flag
+	   store and a precedence.
+  RETURNS: TRUE iff sort simplification was possible.
+           If <Document> is true or the split level of the
+	   used declaration clauses requires copying a 
+	   simplified copy of the clause is returned in 
+	   <*Changed>.
+	   Otherwise the clause is destructively
+	   simplified.
+***********************************************************/
+{ 
+  if (Theory != (SORTTHEORY)NULL) {
+    TERM      Atom,Term;
+    SOJU      SortPair;
+    SORT      TermSort,LitSort;
+    LIST      Indexes,NewClauses,Clauses,Scan;
+    int       i,lc,j,OldSplitLevel;
+    CLAUSE    Copy;
+    CONDITION Cond;
+
+#ifdef CHECK
+    if (!clause_IsClause(Clause, Flags, Precedence)) {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In red_SortSimplification :");
+      misc_ErrorReport(" Illegal input.\n");
+      misc_FinishErrorReport();
+    }
+    clause_Check(Clause, Flags, Precedence);
+#endif
+
+    lc            = clause_LastConstraintLitIndex(Clause);
+    i             = clause_FirstLitIndex();
+    j             = 0;
+    OldSplitLevel = clause_SplitLevel(Clause);
+    Copy          = Clause;
+    Indexes       = list_Nil();
+    Clauses       = list_Nil();
+  
+    while (i <= lc) {
+
+      Atom        = clause_LiteralAtom(clause_GetLiteral(Copy, i));
+      Term        = term_FirstArgument(Atom);
+      SortPair    = sort_ComputeSortNoResidues(Theory, Term, Copy, i,
+					       Flags, Precedence);
+      TermSort    = sort_PairSort(SortPair);
+      NewClauses  = sort_ConditionClauses(sort_PairCondition(SortPair));
+      sort_ConditionPutClauses(sort_PairCondition(SortPair),list_Nil());
+      LitSort     = sort_TheorySortOfSymbol(Theory,term_TopSymbol(Atom));
+
+      if ((Cond = sort_TheoryIsSubsortOfNoResidues(Theory, TermSort, LitSort)) != (CONDITION)NULL) {
+
+	if (j == 0 && flag_GetFlagValue(Flags, flag_PSSI)) {
+	  fputs("\nSortSimplification: ", stdout);
+	  clause_Print(Copy);
+	  fputs(" ==>[ ", stdout);
+	}
+
+	NewClauses = list_Nconc(NewClauses,sort_ConditionClauses(Cond));
+	sort_ConditionPutClauses(Cond,list_Nil());
+	sort_ConditionDelete(Cond);
+
+	for (Scan = NewClauses; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+	  if (Clause == Copy && 
+	      (Document || 
+	       prfs_SplitLevelCondition(clause_SplitLevel(list_Car(Scan)),OldSplitLevel,Level)))
+	    Copy   = clause_Copy(Clause);
+	  clause_UpdateSplitDataFromPartner(Copy, list_Car(Scan));
+	  if (flag_GetFlagValue(Flags, flag_PSSI))
+	    printf("%d ",clause_Number(list_Car(Scan)));
+	}
+
+	if (Document)
+	  Indexes = list_Cons((POINTER)(i+j), Indexes);
+
+	clause_DeleteLiteral(Copy, i, Flags, Precedence);
+	Clauses = list_Nconc(NewClauses,Clauses);
+	j++;
+	lc--;
+      }	   
+      else {
+	list_Delete(NewClauses);
+	i++;
+      }
+      sort_DeleteSortPair(SortPair);
+      sort_Delete(LitSort);
+    }
+
+#ifdef CHECK
+    clause_Check(Copy, Flags, Precedence);
+#endif
+
+    if (j > 0) {
+      if (Document)
+	red_DocumentSortSimplification(Copy,Indexes,Clauses);
+      else
+	list_Delete(Clauses);
+      clause_ReInit(Copy, Flags, Precedence);
+      if (flag_GetFlagValue(Flags, flag_PSSI)) {
+	fputs("] ", stdout);
+	clause_Print(Copy);
+      }
+      if (Copy != Clause)
+	*Changed = Copy;
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+static void red_ExchangeClauses(CLAUSE *RedClause, CLAUSE *Copy, LIST *Result)
+/**********************************************************
+  INPUT:   Two pointers to clauses and a pointer to a list.
+  RETURNS: Nothing.
+  EFFECT:  If *Copy is NULL, nothing is done. Otherwise *RedClause
+           is added to the list, *Copy is assigned to *RedClause,
+	   and NULL is assigned to *Copy.
+***********************************************************/
+{
+  if (*Copy) {
+    *Result    = list_Cons(*RedClause,*Result);
+    *RedClause = *Copy;
+    *Copy      = (CLAUSE)NULL;
+  }
+}
+     
+
+
+static BOOL red_SimpleStaticReductions(CLAUSE *RedClause, FLAGSTORE Flags,
+				       PRECEDENCE Precedence, LIST* Result)
+/**********************************************************
+  INPUT:   A clause (by reference), a flag store and a
+           precedence.
+  RETURNS: TRUE if <*RedClause> is redundant.
+	   If the <DocProof> flag is false and no copying is necessary
+	   with respect to splitting, the clause is destructively changed,
+	   otherwise (intermediate) copies are made and returned in <*Result>.
+  EFFECT:  Used reductions are tautology deletion and 
+           obvious reductions.
+***********************************************************/
+{
+  CLAUSE Copy;
+  BOOL   DocProof;
+
+#ifdef CHECK
+  if (!clause_IsClause(*RedClause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_SimpleStaticReductions :");
+    misc_ErrorReport(" Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(*RedClause, Flags, Precedence);
+#endif
+
+  Copy = (CLAUSE)NULL;
+  DocProof = flag_GetFlagValue(Flags, flag_DOCPROOF);
+
+  if (flag_GetFlagValue(Flags, flag_RTAUT) != flag_RTAUTOFF &&
+      red_Tautology(*RedClause, Flags, Precedence))
+    return TRUE;
+
+  if (flag_GetFlagValue(Flags, flag_ROBV)) {
+    red_ObviousReductions(*RedClause, DocProof, Flags, Precedence, &Copy);
+    red_ExchangeClauses(RedClause, &Copy, Result);
+  }
+
+  if (flag_GetFlagValue(Flags, flag_RCON)) {
+    red_Condensing(*RedClause, DocProof, Flags, Precedence, &Copy);
+    red_ExchangeClauses(RedClause, &Copy, Result);
+  }
+
+  return FALSE;    
+}
+
+  
+
+
+static BOOL red_StaticReductions(PROOFSEARCH Search, CLAUSE *Clause,
+				 CLAUSE *Subsumer, LIST* Result, NAT Mode)
+/**********************************************************
+  INPUT:   A proof search object, a clause (by reference) to be reduced, 
+           a shared index of clauses and the mode of the reductions,
+	   determining which sets (Usable, WorkedOff) in <Search>
+	   are considered for reductions.
+  RETURNS: TRUE iff the clause is redundant.
+	   If the <DocProof> flag is false and no copying is necessary
+	   with respect  to splitting, the clause is destructively changed,
+	   otherwise (intermediate) copies are made and returned in <*Result>.
+           If <Clause> gets redundant with respect to forward subsumption,
+	   the subsuming clause is returned in <*Subsumer>.
+  EFFECT:  Used reductions are tautology deletion, obvious reductions,
+           forward subsumption, forward rewriting, forward contextual
+	   rewriting, forward matching replacement resolution,
+	   sort simplification, unit conflict and static soft typing.
+	   Depending on <Mode>, then clauses are reduced with respect
+	   to WorkedOff or  Usable Clauses.
+***********************************************************/
+{ 
+  CLAUSE       Copy;
+  BOOL         Redundant;
+  SHARED_INDEX Index;
+  FLAGSTORE    Flags;
+  PRECEDENCE   Precedence;
+
+  Flags      = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+
+#ifdef CHECK
+  if (!clause_IsClause(*Clause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_StaticReductions:");
+    misc_ErrorReport(" Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(*Clause, Flags, Precedence);
+#endif
+
+  Index     = (red_OnlyWorkedOffMode(Mode) ? 
+	       prfs_WorkedOffSharingIndex(Search) : prfs_UsableSharingIndex(Search));
+  Copy      = (CLAUSE)NULL;
+  Redundant = red_SimpleStaticReductions(Clause, Flags, Precedence, Result);
+
+  if (Redundant)
+    return Redundant;
+
+  /* Assignment Equation Deletion */
+  if (flag_GetFlagValue(Flags, flag_RAED) != flag_RAEDOFF &&
+      red_AssignmentEquationDeletion(*Clause, Flags, Precedence, &Copy,
+				     prfs_NonTrivClauseNumber(Search), 
+				     (flag_GetFlagValue(Flags, flag_RAED) == flag_RAEDPOTUNSOUND))) {
+    red_ExchangeClauses(Clause, &Copy, Result);
+    if (clause_IsEmptyClause(*Clause))
+      return FALSE;
+  }
+
+  /* Subsumption */
+  if (flag_GetFlagValue(Flags, flag_RFSUB)) {
+    *Subsumer = red_ForwardSubsumption(*Clause, Index, Flags, Precedence);
+    if ((Redundant = (*Subsumer != (CLAUSE)NULL)))
+      return Redundant;
+  }
+
+  /* Forward Rewriting and Forward Contextual Rewriting */
+  if ((flag_GetFlagValue(Flags, flag_RFREW) && 
+       red_RewriteRedClause(*Clause, Index, Flags, Precedence,
+			   &Copy, prfs_LastBacktrackLevel(Search))) ||
+      (flag_GetFlagValue(Flags, flag_RFCRW) &&
+       red_ContextualRewriting(Search, *Clause, Mode,
+			       prfs_LastBacktrackLevel(Search), &Copy))) {
+    red_ExchangeClauses(Clause, &Copy, Result);
+    Redundant = red_SimpleStaticReductions(Clause, Flags, Precedence, Result);
+    if (Redundant)
+      return Redundant;
+    if (clause_IsEmptyClause(*Clause))
+      return FALSE;
+    if (flag_GetFlagValue(Flags, flag_RFSUB)) {
+      *Subsumer = red_ForwardSubsumption(*Clause, Index, Flags, Precedence);
+      if ((Redundant = (*Subsumer != (CLAUSE)NULL)))
+	return Redundant;
+    }
+  }
+
+  /* Sort Simplification */
+  if (red_OnlyWorkedOffMode(Mode) && flag_GetFlagValue(Flags, flag_RSSI)) { 
+    red_SortSimplification(prfs_DynamicSortTheory(Search), *Clause,
+			   prfs_LastBacktrackLevel(Search),
+			   flag_GetFlagValue(Flags, flag_DOCPROOF),
+			   Flags, Precedence, &Copy);
+    red_ExchangeClauses(Clause, &Copy, Result);
+    if (clause_IsEmptyClause(*Clause))
+      return FALSE;    
+  }
+
+  /* Matching Replacement Resolution */
+  if (flag_GetFlagValue(Flags, flag_RFMRR)) {
+    red_MatchingReplacementResolution(*Clause, Index, Flags, Precedence, 
+				      &Copy, prfs_LastBacktrackLevel(Search));
+    red_ExchangeClauses(Clause, &Copy, Result);
+    if (clause_IsEmptyClause(*Clause))
+      return FALSE;
+  }
+
+  /* Unit Conflict */
+  if (flag_GetFlagValue(Flags, flag_RUNC)) {
+    red_UnitConflict(*Clause, Index, Flags, Precedence,
+		     &Copy, prfs_LastBacktrackLevel(Search));
+    red_ExchangeClauses(Clause, &Copy, Result);
+    if (clause_IsEmptyClause(*Clause))
+      return FALSE;
+  }
+
+  /* Static Soft Typing */
+  if (red_OnlyWorkedOffMode(Mode) && flag_GetFlagValue(Flags, flag_RSST))
+    Redundant = red_ClauseDeletion(prfs_StaticSortTheory(Search),*Clause,
+				   Flags, Precedence);
+  
+#ifdef CHECK
+  clause_Check(*Clause, Flags, Precedence);
+#endif
+
+  return Redundant;
+}
+
+static BOOL red_SelectedStaticReductions(PROOFSEARCH Search, CLAUSE *Clause, 
+					 CLAUSE *Subsumer, LIST* Result,
+					 NAT Mode)
+/**********************************************************
+  INPUT:   A proof search object, a clause (by reference) to be reduced, 
+           and the mode of the reductions, determining which sets
+	   (Usable, WorkedOff) in <Search> are considered for reductions.
+  EFFECT:  Used reductions are tautology deletion, obvious reductions,
+           forward subsumption, forward rewriting, forward matching
+	   replacement resolution, sort simplification, unit conflict
+	   and static soft typing.
+	   Depending on <Mode>, the clauses are reduced with respect
+	   to WorkedOff and/or Usable Clauses.
+  RETURNS: TRUE iff the clause is redundant.
+	   If the <DocProof> flag is false and no copying is necessary
+	   with respect to splitting, the clause is destructively changed,
+	   otherwise (intermediate) copies are made and returned in <*Result>.
+           If <Clause> gets redundant with respect to forward subsumption,
+	   the subsuming clause is returned in <*Subsumer>.
+***********************************************************/
+{ 
+  CLAUSE       Copy;
+  BOOL         Redundant ,Rewritten, Tried, ContextualRew, StandardRew;
+  SHARED_INDEX WoIndex,UsIndex;
+  FLAGSTORE    Flags;
+  PRECEDENCE   Precedence;
+
+  Flags      = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+
+#ifdef CHECK
+  if (!clause_IsClause(*Clause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_SelectedStaticReductions:");
+    misc_ErrorReport(" Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(*Clause, Flags, Precedence);
+#endif
+
+  WoIndex = (SHARED_INDEX)NULL;
+  UsIndex = (SHARED_INDEX)NULL;
+  if (red_WorkedOffMode(Mode))
+    WoIndex   = prfs_WorkedOffSharingIndex(Search);
+  if (red_UsableMode(Mode))
+    UsIndex   = prfs_UsableSharingIndex(Search);
+  Copy      = (CLAUSE)NULL;
+  Redundant = red_SimpleStaticReductions(Clause, Flags, Precedence, Result);
+
+  if (Redundant)
+    return Redundant;
+
+  if (flag_GetFlagValue(Flags, flag_RAED) != flag_RAEDOFF &&
+      red_AssignmentEquationDeletion(*Clause, Flags, Precedence, &Copy,
+				     prfs_NonTrivClauseNumber(Search), 
+				     (flag_GetFlagValue(Flags, flag_RAED)==flag_RAEDPOTUNSOUND))) {
+    red_ExchangeClauses(Clause, &Copy, Result);
+    if (clause_IsEmptyClause(*Clause))
+      return FALSE;
+  }
+
+  if (flag_GetFlagValue(Flags, flag_RFSUB)) {
+    *Subsumer = (CLAUSE)NULL;
+    if (WoIndex != NULL) {
+      *Subsumer = red_ForwardSubsumption(*Clause, WoIndex, Flags, Precedence);
+      if (*Subsumer != (CLAUSE)NULL)
+	return TRUE;
+    }
+    if (UsIndex != NULL) {
+      *Subsumer = red_ForwardSubsumption(*Clause, UsIndex, Flags, Precedence);
+      if (*Subsumer != (CLAUSE)NULL)
+	return TRUE;
+    }
+  }
+
+  StandardRew   = flag_GetFlagValue(Flags, flag_RFREW);
+  ContextualRew = flag_GetFlagValue(Flags, flag_RFCRW);
+
+  Rewritten = (StandardRew || ContextualRew);
+  Tried     = FALSE;
+  while (Rewritten) {
+    Rewritten = FALSE;
+
+    if (WoIndex != NULL &&
+	((StandardRew &&
+	  red_RewriteRedClause(*Clause, WoIndex, Flags, Precedence, &Copy, 
+			       prfs_LastBacktrackLevel(Search))) ||
+	 (ContextualRew &&
+	  red_ContextualRewriting(Search, *Clause, red_WORKEDOFF, 
+				  prfs_LastBacktrackLevel(Search), &Copy)))) {
+      Rewritten = TRUE;
+      red_ExchangeClauses(Clause, &Copy, Result);
+      Redundant = red_SimpleStaticReductions(Clause, Flags,
+					     Precedence, Result);
+      if (Redundant)
+	return Redundant;
+      if (clause_IsEmptyClause(*Clause))
+	return FALSE;
+      if (flag_GetFlagValue(Flags, flag_RFSUB)) {
+	*Subsumer = (CLAUSE)NULL;
+	*Subsumer = red_ForwardSubsumption(*Clause, WoIndex,
+					   Flags, Precedence);
+	if (*Subsumer != (CLAUSE)NULL)
+	  return TRUE;       /* Clause is redundant */
+	if (UsIndex != NULL) {
+	  *Subsumer = red_ForwardSubsumption(*Clause, UsIndex,
+					     Flags, Precedence);
+	  if (*Subsumer != (CLAUSE)NULL)
+	    return TRUE;
+	}
+      }
+    }
+
+    if (UsIndex != NULL &&
+	(!Tried || Rewritten) && 
+	((StandardRew &&
+	  red_RewriteRedClause(*Clause, UsIndex, Flags, Precedence, 
+			       &Copy, prfs_LastBacktrackLevel(Search))) ||
+	 (ContextualRew &&
+	  red_ContextualRewriting(Search, *Clause, red_USABLE,
+				  prfs_LastBacktrackLevel(Search), &Copy)))) {
+      Rewritten = TRUE;
+      red_ExchangeClauses(Clause, &Copy, Result);
+      Redundant = red_SimpleStaticReductions(Clause, Flags,
+					     Precedence, Result);
+      if (Redundant)
+	return Redundant;
+      if (clause_IsEmptyClause(*Clause))
+	return FALSE;
+      if (flag_GetFlagValue(Flags, flag_RFSUB)) {
+	*Subsumer = (CLAUSE)NULL;
+	if (WoIndex != NULL)
+	  *Subsumer = red_ForwardSubsumption(*Clause, WoIndex,
+					     Flags, Precedence);
+	if (*Subsumer != (CLAUSE)NULL)
+	  return TRUE;
+	*Subsumer = red_ForwardSubsumption(*Clause, UsIndex,
+					   Flags, Precedence);
+	if (*Subsumer != (CLAUSE)NULL)
+	  return TRUE;
+      }
+    }
+
+    Tried = TRUE;
+  } /* end of while(Rewritten) */
+
+
+  if (flag_GetFlagValue(Flags, flag_RSSI)) { 
+    red_SortSimplification(prfs_DynamicSortTheory(Search), *Clause,
+			   prfs_LastBacktrackLevel(Search),
+			   flag_GetFlagValue(Flags, flag_DOCPROOF),
+			   Flags, Precedence, &Copy);
+    red_ExchangeClauses(Clause, &Copy, Result);
+    if (clause_IsEmptyClause(*Clause))
+      return FALSE; 
+  }
+     
+  if (flag_GetFlagValue(Flags, flag_RFMRR)) {
+    if (WoIndex)
+      red_MatchingReplacementResolution(*Clause, WoIndex, Flags, Precedence,
+					&Copy, prfs_LastBacktrackLevel(Search));
+    red_ExchangeClauses(Clause, &Copy, Result);
+    if (clause_IsEmptyClause(*Clause))
+      return FALSE;
+    if (UsIndex)
+      red_MatchingReplacementResolution(*Clause, UsIndex, Flags, Precedence,
+					&Copy, prfs_LastBacktrackLevel(Search));
+    red_ExchangeClauses(Clause, &Copy, Result);
+    if (clause_IsEmptyClause(*Clause))
+      return FALSE;
+  }
+
+  if (flag_GetFlagValue(Flags, flag_RUNC)) {
+    if (WoIndex)
+      red_UnitConflict(*Clause, WoIndex, Flags, Precedence,
+		       &Copy, prfs_LastBacktrackLevel(Search));
+    red_ExchangeClauses(Clause, &Copy, Result);
+    if (clause_IsEmptyClause(*Clause))
+      return FALSE;
+    if (UsIndex)
+      red_UnitConflict(*Clause, UsIndex, Flags, Precedence,
+		       &Copy, prfs_LastBacktrackLevel(Search));
+    red_ExchangeClauses(Clause, &Copy, Result);
+    if (clause_IsEmptyClause(*Clause))
+      return FALSE;
+  }
+
+  if (flag_GetFlagValue(Flags, flag_RSST))
+    Redundant = red_ClauseDeletion(prfs_StaticSortTheory(Search),*Clause,
+				   Flags, Precedence);
+  
+#ifdef CHECK
+  clause_Check(*Clause, Flags, Precedence);
+#endif
+
+  return Redundant;
+}
+
+
+CLAUSE red_ReductionOnDerivedClause(PROOFSEARCH Search, CLAUSE Clause,
+				    NAT Mode)
+/**************************************************************
+  INPUT:   A proof search object, a derived clause and a mode
+	   indicating which indexes should be used for reductions.
+  RETURNS: The non-redundant clause after reducing <Clause>,
+           NULL if <Clause> is redundant.
+  EFFECT:  Clauses probably generated, but redundant are kept according
+           to the <DocProof> flag and the split level of involved clauses.
+	   depending on <Mode>, then clauses are reduced
+	   with respect to WorkedOff and/or Usable Clauses.
+***************************************************************/
+{
+  CLAUSE RedClause;
+  LIST   Redundant;
+
+#ifdef CHECK
+  cont_SaveState();
+#endif
+
+  Redundant = list_Nil();
+  RedClause = (CLAUSE)NULL;
+
+  if (red_StaticReductions(Search,&Clause,&RedClause,&Redundant,Mode)) {
+    /* Clause is redundant */
+    red_HandleRedundantDerivedClauses(Search, Redundant, Clause);
+    list_Delete(Redundant);
+    if (RedClause &&
+	prfs_SplitLevelCondition(clause_SplitLevel(RedClause),clause_SplitLevel(Clause),
+				 prfs_LastBacktrackLevel(Search))) {
+      split_KeepClauseAtLevel(Search,Clause,clause_SplitLevel(RedClause));
+    }
+    else
+      if (flag_GetFlagValue(prfs_Store(Search), flag_DOCPROOF))
+	prfs_InsertDocProofClause(Search,Clause);
+      else
+	clause_Delete(Clause);
+    Clause = (CLAUSE)NULL;
+  }
+  else {
+    red_HandleRedundantDerivedClauses(Search, Redundant, Clause);
+    list_Delete(Redundant);
+  }
+
+#ifdef CHECK
+  cont_CheckState();
+#endif
+
+  return Clause;
+}
+
+CLAUSE red_CompleteReductionOnDerivedClause(PROOFSEARCH Search, CLAUSE Clause,
+					    NAT Mode)
+/**************************************************************
+  INPUT:   A proof search object, a derived clause and a mode determining
+	   which clauses to consider for reduction.
+  RETURNS: The non-redundant clause after reducing <Clause>,
+           NULL if <Clause> is redundant.
+  EFFECT:  Clauses probably generated, but redundant are kept according
+           to the <DocProof> flag and the split level of involved clauses.
+	   The clause is reduced with respect to all indexes determined
+	   by <Mode>
+***************************************************************/
+{
+  CLAUSE RedClause;
+  LIST   Redundant;
+
+#ifdef CHECK
+  cont_SaveState();
+#endif
+
+  Redundant = list_Nil();
+  RedClause = (CLAUSE)NULL;
+
+  if (red_SelectedStaticReductions(Search,&Clause,&RedClause,&Redundant,Mode)) {
+    /* <Clause> is redundant */
+    red_HandleRedundantDerivedClauses(Search, Redundant, Clause);
+    list_Delete(Redundant);
+    if (RedClause && 
+	prfs_SplitLevelCondition(clause_SplitLevel(RedClause),clause_SplitLevel(Clause),
+				 prfs_LastBacktrackLevel(Search))) {
+      split_KeepClauseAtLevel(Search, Clause, clause_SplitLevel(RedClause));
+    }
+    else
+      if (flag_GetFlagValue(prfs_Store(Search), flag_DOCPROOF))
+	prfs_InsertDocProofClause(Search, Clause);
+      else
+	clause_Delete(Clause);
+    Clause = (CLAUSE)NULL;
+  }
+  else {
+    red_HandleRedundantDerivedClauses(Search, Redundant, Clause);
+    list_Delete(Redundant);
+  }
+
+#ifdef CHECK
+  cont_CheckState();
+#endif
+
+  return Clause;
+}
+
+
+LIST red_BackReduction(PROOFSEARCH Search, CLAUSE Clause, NAT Mode)
+/**************************************************************
+  INPUT:   A proof search object, a clause and a mode flag.
+  RETURNS: A list of reduced clauses in usable and worked-off
+           (depending on <Mode>) in <Search> with respect to <Clause>.
+	   The original clauses that become redundant are either deleted
+	   or kept for proof documentation or splitting.
+  EFFECT:  The original clauses that become redundant are either deleted
+	   or kept for proof documentation or splitting.
+***************************************************************/
+{
+  LIST Result, Redundant;
+  FLAGSTORE  Flags;
+  PRECEDENCE Precedence;
+
+#ifdef CHECK
+  cont_SaveState();
+#endif
+
+  Result    = list_Nil();
+  Flags      = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+
+  /* Subsumption */
+  if (flag_GetFlagValue(Flags, flag_RBSUB)) {
+    Redundant = list_Nil();
+    if (red_WorkedOffMode(Mode))
+      Redundant = red_BackSubsumption(Clause,
+				      prfs_WorkedOffSharingIndex(Search),
+				      Flags, Precedence);
+    if (red_UsableMode(Mode))
+      Redundant = list_Nconc(Redundant,
+			     red_BackSubsumption(Clause,
+						 prfs_UsableSharingIndex(Search),
+						 Flags, Precedence));
+    red_HandleRedundantIndexedClauses(Search, Redundant, Clause);
+    list_Delete(Redundant);
+  }
+
+  /* Matching Replacement Resolution */
+  if (flag_GetFlagValue(Flags, flag_RBMRR)) {
+    Redundant = list_Nil();
+    if (red_WorkedOffMode(Mode))
+      Redundant = red_BackMatchingReplacementResolution(Clause,
+							prfs_WorkedOffSharingIndex(Search),
+							Flags, Precedence, &Result);
+    if (red_UsableMode(Mode))
+      Redundant = list_Nconc(Redundant,
+			     red_BackMatchingReplacementResolution(Clause,
+								   prfs_UsableSharingIndex(Search),
+								   Flags, Precedence, &Result));
+    red_HandleRedundantIndexedClauses(Search, Redundant, Clause);
+    list_Delete(Redundant);
+  }
+
+  /* Standard Rewriting */
+  if (flag_GetFlagValue(Flags, flag_RBREW)) {
+    Redundant = list_Nil();
+    if (red_WorkedOffMode(Mode))
+      Redundant = red_BackRewriting(Clause,prfs_WorkedOffSharingIndex(Search),
+				    Flags, Precedence, &Result);
+    if (red_UsableMode(Mode))
+      Redundant = list_Nconc(Redundant,
+			     red_BackRewriting(Clause,
+					       prfs_UsableSharingIndex(Search),
+					       Flags, Precedence, &Result));
+
+    red_HandleRedundantIndexedClauses(Search, Redundant, Clause);
+    list_Delete(Redundant);
+  }
+
+  /* Contextual Rewriting */
+  if (flag_GetFlagValue(Flags, flag_RBCRW)) {
+    Redundant = list_Nil();
+    if (red_WorkedOffMode(Mode))
+      Redundant = red_BackContextualRewriting(Search, Clause, red_WORKEDOFF,
+					      &Result);
+    if (red_UsableMode(Mode))
+      Redundant = list_Nconc(Redundant,
+			     red_BackContextualRewriting(Search, Clause,
+							 red_USABLE, &Result));
+
+    red_HandleRedundantIndexedClauses(Search, Redundant, Clause);
+    list_Delete(Redundant);
+  }
+
+#ifdef CHECK
+  cont_CheckState();
+#endif
+
+  return Result;
+}
+
+
+static __inline__ LIST red_MergeClauseListsByWeight(LIST L1, LIST L2)
+/**************************************************************
+  INPUT:   Two lists of clauses, sorted by weight.
+  RETURNS: 
+  EFFECT:  
+***************************************************************/
+{
+  return list_NNumberMerge(L1, L2, (NAT (*)(POINTER))clause_Weight);
+}
+
+
+LIST red_CompleteReductionOnDerivedClauses(PROOFSEARCH Search,
+					   LIST DerivedClauses, NAT Mode,
+					   int Bound, NAT BoundMode,
+					   int *BoundApplied)
+/**************************************************************
+  INPUT:   A proof search object, a list of newly derived (unshared) clauses,
+	   a mode determining which clause lists to consider for reduction,
+	   a bound and a bound mode to cut off generated clauses.
+  RETURNS: A list of empty clauses that may be derived during the
+           reduction process.
+           <*BoundApplied> is set to the mode dependent value of the
+	   smallest clause if a clause is deleted because of a bound.
+  EFFECT:  The <DerivedClauses> are destructively reduced and reduced clauses
+           from the indexes are checked out and all finally reduced clauses
+	   are checked into the indexes. Depending on <Mode> either the
+	   WorkedOff, Usable or both indexes are considered.
+	   The <DocProof> Flag is considered.
+***************************************************************/
+{
+  LIST   EmptyClauses,NewClauses,Scan;
+  NAT    ClauseBound;
+  CLAUSE Clause;
+  FLAGSTORE Flags;
+
+#ifdef CHECK
+  cont_SaveState();
+#endif
+
+  EmptyClauses   = list_Nil();
+  DerivedClauses = clause_ListSortWeighed(DerivedClauses);
+  ClauseBound    = 0;
+  Flags          = prfs_Store(Search);
+
+  while (!list_Empty(DerivedClauses)) {
+#ifdef WIN
+    clock_PingOneSecond();
+#endif
+    Clause     = list_NCar(&DerivedClauses);
+    if (prfs_SplitStackEmpty(Search))        /* Otherwise splitting not compatible with bound deletion */
+      Clause = red_CompleteReductionOnDerivedClause(Search, Clause, Mode);
+
+    if (Clause != NULL && BoundMode != flag_BOUNDMODEUNLIMITED &&
+	Bound != flag_BOUNDSTARTUNLIMITED && !clause_IsFromInput(Clause) &&
+	!clause_IsFromSplitting(Clause)) {
+      switch (BoundMode) {
+      case flag_BOUNDMODERESTRICTEDBYWEIGHT:
+	ClauseBound = clause_Weight(Clause);
+	break;
+      case flag_BOUNDMODERESTRICTEDBYDEPTH:
+	ClauseBound = clause_ComputeTermDepth(Clause);
+	break;
+      default:
+	misc_StartUserErrorReport();
+	misc_UserErrorReport("\n Error while applying bound restrictions:");
+	misc_UserErrorReport("\n You selected an unknown bound mode.\n");
+	misc_FinishUserErrorReport();
+      }
+      if (ClauseBound > Bound) {
+	if (flag_GetFlagValue(Flags, flag_PBDC)) {
+	  fputs("\nDeleted by bound: ", stdout);
+	  clause_Print(Clause);
+	}
+	clause_Delete(Clause);
+	if (*BoundApplied == -1 || ClauseBound < *BoundApplied)
+	  *BoundApplied = ClauseBound;
+	Clause = (CLAUSE)NULL;
+      }
+    }
+
+    if (Clause != (CLAUSE)NULL &&       /* For clauses below bound, splitting is */
+	!prfs_SplitStackEmpty(Search))  /* compatible with bound deletion */
+      Clause = red_CompleteReductionOnDerivedClause(Search, Clause, Mode);
+	
+    if (Clause) {	
+      prfs_IncKeptClauses(Search);
+      if (flag_GetFlagValue(Flags, flag_PKEPT)) {
+	fputs("\nKept: ", stdout); 
+	clause_Print(Clause);
+      }
+      if (clause_IsEmptyClause(Clause))
+	EmptyClauses = list_Cons(Clause,EmptyClauses);
+      else {
+	NewClauses = red_BackReduction(Search, Clause, Mode);
+	prfs_IncDerivedClauses(Search, list_Length(NewClauses));
+	if (flag_GetFlagValue(Flags, flag_PDER))
+	  for (Scan=NewClauses; !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+	    fputs("\nDerived: ", stdout); 
+	    clause_Print(list_Car(Scan));
+	  }
+	NewClauses = split_ExtractEmptyClauses(NewClauses,&EmptyClauses);
+
+	prfs_InsertUsableClause(Search,Clause);
+	NewClauses = list_NumberSort(NewClauses, (NAT (*) (POINTER)) clause_Weight);
+	DerivedClauses = red_MergeClauseListsByWeight(DerivedClauses,NewClauses);
+      }
+    }
+  }
+
+#ifdef CHECK
+  cont_CheckState();
+#endif
+
+  return EmptyClauses;
+}
+
+
+
+static CLAUSE red_CDForwardSubsumer(CLAUSE RedCl, st_INDEX Index,
+				    FLAGSTORE Flags, PRECEDENCE Precedence)
+/**********************************************************
+  INPUT:   A pointer to a non-empty clause, an index of 
+           clauses, a flag store and a precedence.
+  RETURNS: The first clause from the Approx Set which 
+           subsumes 'RedCl'.
+***********************************************************/
+{
+  TERM   Atom,AtomGen;
+  LIST   LitScan;
+  int    i,length;
+  CLAUSE CandCl;
+
+#ifdef CHECK
+  if (!clause_IsClause(RedCl, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_CDForwardSubsumer :");
+    misc_ErrorReport(" Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(RedCl, Flags, Precedence);
+#endif
+
+  length  = clause_Length(RedCl);
+
+  for (i = 0; i < length; i++) {
+    Atom     = clause_GetLiteralAtom(RedCl, i);
+    AtomGen  = st_ExistGen(cont_LeftContext(), Index, Atom);
+
+    while (AtomGen) {
+      for (LitScan = term_SupertermList(AtomGen); 
+	   !list_Empty(LitScan); LitScan = list_Cdr(LitScan)) {
+	CandCl = clause_LiteralOwningClause(list_Car(LitScan));
+
+	if (clause_GetLiteral(CandCl,clause_FirstLitIndex()) == (LITERAL)list_Car(LitScan) &&
+	    subs_Subsumes(CandCl, RedCl, clause_FirstLitIndex(), i)) {
+	  st_CancelExistRetrieval();
+	  return CandCl;
+	}
+      }
+      AtomGen = st_NextCandidate();  
+    }
+  }
+  return (CLAUSE)NULL;
+}
+
+
+static BOOL red_CDForwardSubsumption(CLAUSE RedClause, st_INDEX Index,
+				     FLAGSTORE Flags, PRECEDENCE Precedence)
+/**********************************************************
+  INPUT:   A clause, an index of clauses, a flag store and
+           a precedence.
+  RETURNS: The boolean value TRUE if the clause is subsumed
+           by an indexed clause, if so, the clause is deleted,
+	   either really or locally.
+***********************************************************/
+{ 
+  BOOL   IsSubsumed;
+  CLAUSE Subsumer;
+
+#ifdef CHECK
+  if (!clause_IsClause(RedClause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_CDForwardSubSumption :");
+    misc_ErrorReport(" Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(RedClause, Flags, Precedence);
+#endif
+  IsSubsumed = FALSE;
+  Subsumer   = red_CDForwardSubsumer(RedClause, Index, Flags, Precedence);
+
+  if (clause_Exists(Subsumer)) {
+    IsSubsumed = TRUE;
+
+    if (flag_GetFlagValue(Flags, flag_DOCSST) &&
+	flag_GetFlagValue(Flags, flag_PSUB)) {
+      fputs("\nFSubsumption:", stdout);
+      clause_Print(RedClause);
+      printf(" by %d ",clause_Number(Subsumer));
+    }
+  }
+  return IsSubsumed;
+}
+
+
+static void red_CDBackSubsumption(CLAUSE RedCl, FLAGSTORE Flags,
+				  PRECEDENCE Precedence,
+				  LIST* UsListPt, LIST* WOListPt,
+				  st_INDEX Index)
+/**********************************************************
+  INPUT:   A pointer to a non-empty clause, a flag store, 
+           a precedence, and an index of clauses.
+  RETURNS: Nothing.
+***********************************************************/
+{
+  TERM   Atom,AtomInst;
+  CLAUSE SubsumedCl;
+  LIST   Scan, SubsumedList;
+
+#ifdef CHECK
+  if (!clause_IsClause(RedCl, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_CDBackupSubSumption :");
+    misc_ErrorReport(" Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(RedCl, Flags, Precedence);
+#endif
+
+  SubsumedList = list_Nil();
+
+  if (!clause_IsEmptyClause(RedCl)) {
+    Atom     = clause_GetLiteralAtom(RedCl, clause_FirstLitIndex());
+    AtomInst = st_ExistInstance(cont_LeftContext(), Index, Atom);
+    
+    while(AtomInst) {
+      for (Scan = term_SupertermList(AtomInst); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+	SubsumedCl = clause_LiteralOwningClause(list_Car(Scan));
+	if ((RedCl != SubsumedCl) &&
+	    subs_Subsumes(RedCl, SubsumedCl, clause_FirstLitIndex(), 
+			  clause_LiteralGetIndex(list_Car(Scan))) &&
+	    !list_PointerMember(SubsumedList, SubsumedCl))
+	  SubsumedList = list_Cons(SubsumedCl, SubsumedList);
+      }
+      AtomInst = st_NextCandidate();
+    }
+    
+    for (Scan = SubsumedList; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+      SubsumedCl = list_Car(Scan);
+
+      if (flag_GetFlagValue(Flags, flag_DOCSST) && flag_GetFlagValue(Flags, flag_PSUB)) {
+	fputs("\nBSubsumption: ", stdout);
+	clause_Print(SubsumedCl);
+	printf(" by %d ",clause_Number(RedCl));
+      }
+	     
+
+      if (clause_GetFlag(SubsumedCl,WORKEDOFF)) {
+	*WOListPt = list_PointerDeleteOneElement(*WOListPt, SubsumedCl);
+      }else {
+	*UsListPt = list_PointerDeleteOneElement(*UsListPt, SubsumedCl);
+      }
+      clause_DeleteFlatFromIndex(SubsumedCl, Index);
+    }
+    list_Delete(SubsumedList);
+  }
+}
+
+
+static LIST red_CDDerivables(SORTTHEORY Theory, CLAUSE GivenClause,
+			     FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A sort theory, a clause, a flag store and a
+           precedence.
+  RETURNS: A list of clauses derivable from <GivenClause> and
+           the declaration clauses in <Theory>.
+***************************************************************/
+{
+  LIST ListOfDerivedClauses;
+
+#ifdef CHECK
+  if (!(clause_IsClause(GivenClause, Flags, Precedence))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_CDDeriveables :");
+    misc_ErrorReport(" Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  clause_Check(GivenClause, Flags, Precedence);
+#endif
+  
+  if (clause_HasTermSortConstraintLits(GivenClause))
+    ListOfDerivedClauses = inf_ForwardSortResolution(GivenClause,
+						     sort_TheoryIndex(Theory),
+						     Theory, TRUE,
+						     Flags, Precedence);
+  else
+    ListOfDerivedClauses = inf_ForwardEmptySort(GivenClause,
+						sort_TheoryIndex(Theory),
+						Theory, TRUE,
+						Flags, Precedence);
+  
+  return ListOfDerivedClauses;
+}
+
+
+static BOOL red_CDReduce(SORTTHEORY Theory, CLAUSE RedClause,
+			 FLAGSTORE Flags, PRECEDENCE Precedence, 
+			 LIST *ApproxUsListPt, LIST *ApproxWOListPt,
+			 st_INDEX Index)
+/**************************************************************
+  INPUT:   A sort theory, an unshared clause, a flag store, 
+           a precedence, their index and two pointers to the
+	   sort reduction subproof usable and worked off list.
+  RETURNS: TRUE iff <RedClause> is redundant with respect to 
+           clauses in the index or theory.
+  EFFECT:  <RedClause> is destructively changed.
+           The <DocProof> flag is changed temporarily.
+***************************************************************/
+{
+  CLAUSE Copy;
+
+#ifdef CHECK
+  clause_Check(RedClause, Flags, Precedence);
+#endif
+
+  Copy = (CLAUSE)NULL; /* Only needed for interface */
+  
+  red_ObviousReductions(RedClause, FALSE, Flags, Precedence, &Copy);
+  red_SortSimplification(Theory, RedClause, NAT_MAX, FALSE,
+			 Flags, Precedence, &Copy);
+  
+  if (clause_IsEmptyClause(RedClause))
+    return FALSE;
+
+  red_Condensing(RedClause, FALSE, Flags, Precedence, &Copy);
+
+  if (red_CDForwardSubsumption(RedClause, Index, Flags, Precedence))
+    return TRUE;
+  else {			/* RedClause isn't subsumed! */
+    red_CDBackSubsumption(RedClause, Flags, Precedence,
+			  ApproxUsListPt, ApproxWOListPt, Index);
+    clause_InsertFlatIntoIndex(RedClause, Index);
+    *ApproxUsListPt = list_Cons(RedClause, *ApproxUsListPt);
+  }
+
+#ifdef CHECK
+  clause_Check(RedClause, Flags, Precedence);
+  if (Copy != (CLAUSE)NULL) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In red_CDReduce :");
+    misc_ErrorReport(" Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+    
+#endif
+
+  return FALSE;
+}
+
+
+BOOL red_ClauseDeletion(SORTTHEORY Theory, CLAUSE RedClause, FLAGSTORE Flags,
+			PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A sort theory, a clause (unshared), a flag store
+           and a precedence.
+  RETURNS: TRUE iff the sort constraint of the clause is 
+           unsolvable with respect to the sort theory.
+***************************************************************/
+{
+  if (Theory != (SORTTHEORY)NULL) {
+    CLAUSE   ConstraintClause, GivenClause;
+    LIST     ApproxUsableList, ApproxWOList, EmptyClauses, ApproxDerivables, Scan;
+    int      i,nc, Count, OldClauseCounter;
+    st_INDEX Index;
+
+#ifdef CHECK
+    if (!(clause_IsClause(RedClause, Flags, Precedence))) {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In red_ClauseDeletion :");
+      misc_ErrorReport(" Illegal input.\n");
+      misc_FinishErrorReport();
+    }
+    clause_Check(RedClause, Flags, Precedence);
+#endif
+
+    if (clause_HasEmptyConstraint(RedClause) || !flag_GetFlagValue(Flags, flag_RSST))
+      return FALSE;
+ 
+    if (flag_GetFlagValue(Flags, flag_DOCSST)) {
+      fputs("\n\nStatic Soft Typing tried on: ", stdout);
+      clause_Print(RedClause);
+    }
+
+    Index            = st_IndexCreate();
+    Scan             = list_Nil();
+    nc               = clause_NumOfConsLits(RedClause);
+    OldClauseCounter = clause_Counter();
+
+    /* Make constraint clause, insert it into the Approx-usable-list: */
+
+    for (i = clause_FirstLitIndex(); i < nc; i++)
+      Scan = list_Cons(term_Copy(clause_LiteralAtom(
+						    clause_GetLiteral(RedClause, i))), Scan);
+
+    Scan             = list_NReverse(Scan);
+    ConstraintClause = clause_Create(Scan, list_Nil(), list_Nil(),
+				     Flags, Precedence);
+    list_Delete(Scan);
+    clause_InitSplitData(ConstraintClause);
+    clause_AddParentClause(ConstraintClause, clause_Number(RedClause));
+    clause_AddParentLiteral(ConstraintClause, clause_FirstLitIndex());
+    clause_SetFromClauseDeletion(ConstraintClause);
+    clause_InsertFlatIntoIndex(ConstraintClause, Index);
+    ApproxUsableList = list_List(ConstraintClause);
+    ApproxWOList     = list_Nil();
+
+    /* fputs("\nConstraint clause: ",stdout); clause_Print(ConstraintClause); */
+
+    /* Now the lists are initialized, the subproof is started: */
+
+    EmptyClauses = list_Nil();
+    Count        = 0;
+
+    if (flag_GetFlagValue(Flags, flag_DOCSST)) {
+      puts("\n*************** Static Soft Typing Subproof: ***************");
+      puts("The usable list:");
+      clause_ListPrint(ApproxUsableList);
+      puts("\nThe worked-off list:");
+      clause_ListPrint(ApproxWOList);
+      /* fputs("\nAll indexed clauses: ", stdout);
+	 clause_PrintAllIndexedClauses(ShIndex); */
+    }
+    while (!list_Empty(ApproxUsableList) && list_Empty(EmptyClauses)) {
+      GivenClause      = list_Car(ApproxUsableList); 
+      clause_SetFlag(GivenClause,WORKEDOFF);
+
+      if (flag_GetFlagValue(Flags, flag_DOCSST)) {
+	fputs("\n\tSubproof Given clause: ", stdout);
+	clause_Print(GivenClause); fflush(stdout);
+      }
+      ApproxWOList     = list_Cons(GivenClause, ApproxWOList);
+      ApproxUsableList = list_PointerDeleteOneElement(ApproxUsableList,GivenClause);
+      ApproxDerivables = red_CDDerivables(Theory,GivenClause, Flags, Precedence);
+      ApproxDerivables = split_ExtractEmptyClauses(ApproxDerivables, &EmptyClauses);
+    
+      if (!list_Empty(EmptyClauses)) { /* Exit while loop! */
+	if (flag_GetFlagValue(Flags, flag_DOCSST)) {
+	  fputs("\nStatic Soft Typing not successful: ", stdout);
+	  clause_Print(list_Car(EmptyClauses));
+	}
+	clause_DeleteClauseList(ApproxDerivables); 
+	ApproxDerivables = list_Nil();
+      }
+      else {
+	CLAUSE DerClause;
+	for (Scan = ApproxDerivables; !list_Empty(Scan) && list_Empty(EmptyClauses);
+	     Scan = list_Cdr(Scan)) {
+	  DerClause = (CLAUSE)list_Car(Scan);
+	  if (red_CDReduce(Theory, DerClause, Flags, Precedence,
+			   &ApproxUsableList, &ApproxWOList, Index)) 
+	    clause_Delete(DerClause);
+	  else{
+	    Count++;
+	    if (flag_GetFlagValue(Flags, flag_DOCSST)) {
+	      putchar('\n');
+	      clause_Print(DerClause);
+	    }
+	    if (clause_IsEmptyClause(DerClause))
+	      EmptyClauses = list_Cons(DerClause,EmptyClauses);
+	  }
+	  list_Rplaca(Scan,(CLAUSE)NULL);
+	}
+
+	if (!list_Empty(EmptyClauses)) {
+	  if (flag_GetFlagValue(Flags, flag_DOCSST)) {
+	    fputs(" Static Soft Typing not successful!", stdout);
+	    clause_Print(list_Car(EmptyClauses));
+	  }
+	  clause_DeleteClauseList(ApproxDerivables);    /* There still may be clauses in the list */
+	  ApproxDerivables = list_Nil();
+	}
+	else {
+	  list_Delete(ApproxDerivables); 
+	  ApproxDerivables = list_Nil();
+	}
+      }
+    }
+
+    if (!list_Empty(EmptyClauses)) {
+      if (flag_GetFlagValue(Flags, flag_DOCSST)) {
+	puts("\nStatic Soft Typing failed, constraint solvable.");
+	puts("************  Static Soft Typing Subproof finished. ************");
+      }
+    }
+    else
+      if (flag_GetFlagValue(Flags, flag_PSST)) {
+	fputs("\nStatic Soft Typing deleted: ", stdout);
+	clause_Print(RedClause);
+      }
+
+    /* Cleanup */
+    clause_DeleteClauseListFlatFromIndex(ApproxUsableList, Index);
+    clause_DeleteClauseListFlatFromIndex(ApproxWOList, Index);
+    st_IndexDelete(Index);
+    clause_SetCounter(OldClauseCounter);
+
+    if (!list_Empty(EmptyClauses)) {
+      clause_DeleteClauseList(EmptyClauses);
+      return FALSE;
+    } 
+
+    return TRUE;
+
+#ifdef CHECK
+    clause_Check(RedClause, Flags, Precedence);
+#endif
+  }
+  return FALSE;
+}
+
+LIST red_SatUnit(PROOFSEARCH Search, LIST ClauseList)
+/*********************************************************
+  INPUT:   A proof search object and a list of unshared clauses.
+  RETURNS: A possibly empty list of empty clauses.
+  EFFECT:  Does a shallow saturation of the conclauses depending on the
+           flag_SATUNIT flag.
+	   The <DocProof> flag is considered.
+**********************************************************/
+{
+  CLAUSE Given,Clause;
+  LIST   Scan, Derivables, EmptyClauses, BackReduced;
+  NAT    n, Derived;
+  FLAGSTORE  Flags;
+  PRECEDENCE Precedence;
+
+  Flags        = prfs_Store(Search);
+  Precedence   = prfs_Precedence(Search);
+  Derived      = flag_GetFlagValue(Flags, flag_CNFPROOFSTEPS);
+  EmptyClauses = list_Nil();
+
+  ClauseList = clause_ListSortWeighed(ClauseList);
+  
+  while (!list_Empty(ClauseList) && list_Empty(EmptyClauses)) {
+    Given = (CLAUSE)list_NCar(&ClauseList);
+    Given = red_ReductionOnDerivedClause(Search, Given, red_USABLE);
+    if (Given) {
+      if (clause_IsEmptyClause(Given))
+	EmptyClauses = list_List(Given);
+      else {
+	BackReduced = red_BackReduction(Search, Given, red_USABLE);
+
+	if (Derived != 0) {
+	  Derivables = inf_BoundedDepthUnitResolution(Given,
+						      prfs_UsableSharingIndex(Search),
+						      FALSE, Flags, Precedence);
+	  n          = list_Length(Derivables);
+	  if (n > Derived)
+	    Derived = 0;
+	  else
+	    Derived = Derived - n;
+	}
+	else 
+	  Derivables = list_Nil();
+
+	Derivables  = list_Nconc(BackReduced,Derivables);
+	Derivables  = split_ExtractEmptyClauses(Derivables, &EmptyClauses);
+    
+	prfs_InsertUsableClause(Search, Given);
+
+	for(Scan = Derivables; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+	  Clause     = (CLAUSE)list_Car(Scan);
+	  clause_SetDepth(Clause,0);
+	}
+	ClauseList = list_Nconc(ClauseList,Derivables);
+	Derivables = list_Nil();
+      }
+    }
+  }
+  for(Scan = ClauseList; !list_Empty(Scan); Scan = list_Cdr(Scan))
+    prfs_InsertUsableClause(Search, list_Car(Scan));
+  list_Delete(ClauseList);
+  return EmptyClauses;
+}
+
+static CLAUSE red_SpecialInputReductions(CLAUSE Clause, FLAGSTORE Flags,
+					 PRECEDENCE Precedence)
+/*********************************************************
+  INPUT:   A clause and a flag store.
+  RETURNS: The clause where the logical constants TRUE, FALSE
+           are removed.
+  EFFECT:  The clause is destructively changed.
+**********************************************************/
+{
+  int     i,end;
+  LIST    Indexes;
+  TERM    Atom;
+
+#ifdef CHECK
+  clause_Check(Clause, Flags, Precedence);
+#endif
+
+  Indexes = list_Nil();
+  end     = clause_LastAntecedentLitIndex(Clause);
+    
+  for (i = clause_FirstConstraintLitIndex(Clause); i <= end; i++) {
+    Atom = clause_LiteralAtom(clause_GetLiteral(Clause,i));
+    if (fol_IsTrue(Atom)) 
+      Indexes = list_Cons((POINTER)i,Indexes);
+  }
+
+  end    = clause_LastSuccedentLitIndex(Clause);
+    
+  for (i = clause_FirstSuccedentLitIndex(Clause); i <= end; i++) {
+    Atom = clause_LiteralAtom(clause_GetLiteral(Clause,i));
+    if (fol_IsFalse(Atom)) 
+      Indexes = list_Cons((POINTER)i,Indexes);
+  }
+  
+  clause_DeleteLiterals(Clause,Indexes, Flags, Precedence);
+  list_Delete(Indexes);
+
+  return Clause;
+}
+
+
+LIST red_ReduceInput(PROOFSEARCH Search, LIST ClauseList)
+/*********************************************************
+  INPUT:   A proof search object and a list of unshared clauses.
+  RETURNS: A list of empty clauses.
+  EFFECT:  Interreduces the clause list and inserts the clauses into <Search>.
+	   Keeps track of derived and kept clauses.
+	   Time limits and the DocProof flag are considered.
+**********************************************************/
+{
+  CLAUSE Given;
+  LIST   Scan, EmptyClauses, BackReduced;
+  FLAGSTORE  Flags;
+  PRECEDENCE Precedence;
+
+  Flags        = prfs_Store(Search);
+  Precedence   = prfs_Precedence(Search);
+  EmptyClauses = list_Nil();
+  ClauseList   = clause_ListSortWeighed(list_Copy(ClauseList));
+  ClauseList   = split_ExtractEmptyClauses(ClauseList, &EmptyClauses);
+  
+  while (!list_Empty(ClauseList) && list_Empty(EmptyClauses) &&
+	 (flag_GetFlagValue(Flags,flag_TIMELIMIT) == flag_TIMELIMITUNLIMITED ||
+	  flag_GetFlagValue(Flags, flag_TIMELIMIT) > clock_GetSeconds(clock_OVERALL))) {
+    Given = (CLAUSE)list_NCar(&ClauseList);
+#ifdef CHECK
+    if (!clause_IsClause(Given, Flags, Precedence)) {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In red_ReduceInput :");
+      misc_ErrorReport(" Illegal input.\n");
+      misc_FinishErrorReport();
+    }
+#endif 
+    Given = red_SpecialInputReductions(Given, Flags, Precedence);
+    Given = red_ReductionOnDerivedClause(Search, Given, red_USABLE);
+    if (Given) {
+      prfs_IncKeptClauses(Search);
+      if (clause_IsEmptyClause(Given))
+	EmptyClauses = list_List(Given);
+      else {
+	BackReduced = red_BackReduction(Search, Given, red_USABLE);
+	prfs_IncDerivedClauses(Search, list_Length(BackReduced));
+	BackReduced = split_ExtractEmptyClauses(BackReduced, &EmptyClauses);
+	prfs_InsertUsableClause(Search, Given);
+	BackReduced = clause_ListSortWeighed(BackReduced);
+	ClauseList = red_MergeClauseListsByWeight(ClauseList, BackReduced);
+      }
+    }
+  }
+  for(Scan = ClauseList; !list_Empty(Scan); Scan = list_Cdr(Scan))
+    prfs_InsertUsableClause(Search, list_Car(Scan));
+  list_Delete(ClauseList);
+  return EmptyClauses;
+}
+
+
+LIST red_SatInput(PROOFSEARCH Search) 
+/*********************************************************
+  INPUT:   A proof search object.
+  RETURNS: A list of derived empty clauses.
+  EFFECT:  Does a saturation from the conjectures into the axioms/conjectures
+	   Keeps track of derived and kept clauses. Keeps track of a possible
+	   time limit.
+	   Considers the Usable clauses in <Search> and a possible time limit.
+**********************************************************/
+{
+  CLAUSE     Given;
+  LIST       Scan, ClauseList, Derivables, EmptyClauses;
+  int        n;
+  FLAGSTORE  Flags;
+  PRECEDENCE Precedence;
+
+  Flags        = prfs_Store(Search);
+  Precedence   = prfs_Precedence(Search);
+
+  EmptyClauses = list_Nil();
+  ClauseList   = list_Nil();
+  Scan         = prfs_UsableClauses(Search);
+  n            = list_Length(Scan);
+
+  while(!list_Empty(Scan) &&
+	n > 0 &&
+	(flag_GetFlagValue(Flags,flag_TIMELIMIT) == flag_TIMELIMITUNLIMITED ||
+	 flag_GetFlagValue(Flags, flag_TIMELIMIT) > clock_GetSeconds(clock_OVERALL))) {
+    Given = (CLAUSE)list_Car(Scan);
+    if (clause_GetFlag(Given,CONCLAUSE)) {
+      Derivables = inf_BoundedDepthUnitResolution(Given,
+						  prfs_UsableSharingIndex(Search),
+						  FALSE, Flags, Precedence);
+      n         -= list_Length(Derivables);
+      ClauseList = list_Nconc(Derivables,ClauseList);
+    }
+    Scan = list_Cdr(Scan);
+  }
+  
+  prfs_IncDerivedClauses(Search, list_Length(ClauseList));
+  EmptyClauses = red_ReduceInput(Search, ClauseList);
+  list_Delete(ClauseList);
+  ClauseList   = list_Nil();
+  if (list_Empty(EmptyClauses)) {
+    Scan=prfs_UsableClauses(Search);
+    while (!list_Empty(Scan) &&
+	   n > 0 &&
+	   (flag_GetFlagValue(Flags,flag_TIMELIMIT)==flag_TIMELIMITUNLIMITED ||
+	    flag_GetFlagValue(Flags, flag_TIMELIMIT) > clock_GetSeconds(clock_OVERALL))) {
+      Given = (CLAUSE)list_Car(Scan);
+      if (clause_GetFlag(Given,CONCLAUSE) &&  clause_IsFromInput(Given)) {
+	Derivables = inf_BoundedDepthUnitResolution(Given,
+						    prfs_UsableSharingIndex(Search), 
+						    TRUE, Flags, Precedence);
+	n         -= list_Length(Derivables);
+	ClauseList = list_Nconc(Derivables,ClauseList);
+      }
+      Scan = list_Cdr(Scan);
+    }
+    prfs_IncDerivedClauses(Search, list_Length(ClauseList));
+    EmptyClauses = red_ReduceInput(Search, ClauseList);
+    list_Delete(ClauseList);
+  }
+  return EmptyClauses;
+}
+
+void red_CheckSplitSubsumptionCondition(PROOFSEARCH Search)
+/*********************************************************
+  INPUT:   A proof search object.
+  EFFECT:  For all deleted clauses in the split stack, it
+           is checked whether they are subsumed by some
+	   existing clause. If they are not, a core is dumped.
+	   Used for debugging.
+**********************************************************/
+{
+  LIST   Scan1,Scan2;
+  CLAUSE Clause;
+  FLAGSTORE  Flags;
+  PRECEDENCE Precedence;
+
+  Flags      = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+
+  for (Scan1=prfs_SplitStack(Search);!list_Empty(Scan1);Scan1=list_Cdr(Scan1))
+    for (Scan2=prfs_SplitDeletedClauses(list_Car(Scan1));!list_Empty(Scan2);Scan2=list_Cdr(Scan2)) {
+      Clause = (CLAUSE)list_Car(Scan2);
+      if (!red_ForwardSubsumer(Clause, prfs_WorkedOffSharingIndex(Search),
+			       Flags, Precedence) &&
+	  !red_ForwardSubsumer(Clause, prfs_UsableSharingIndex(Search),
+			       Flags, Precedence) &&
+	  !red_ClauseDeletion(prfs_StaticSortTheory(Search),Clause,
+			      Flags, Precedence)) {
+	misc_StartErrorReport();
+	misc_ErrorReport("\n In red_CheckSplitSubsumptionCondition: No clause found implying ");
+	clause_Print(Clause);
+	misc_ErrorReport("\n Current Split: ");
+	prfs_PrintSplit(list_Car(Scan1));
+	misc_FinishErrorReport();
+      }
+    }
+}
diff --git a/test/spass/rules-red.h b/test/spass/rules-red.h
new file mode 100644
index 0000000000000000000000000000000000000000..2775ab27c902077c63362c2e3461998a3aa70851
--- /dev/null
+++ b/test/spass/rules-red.h
@@ -0,0 +1,111 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                REDUCTION RULES                         * */
+/* *                                                        * */
+/* *  $Module:   REDRULES                                   * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000            * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _REDRULES_
+#define _REDRULES_
+
+#include "sort.h"
+#include "subsumption.h"
+#include "condensing.h"
+#include "search.h"
+#include "rules-split.h"
+#include "rules-inf.h"
+#include "doc-proof.h"
+#include "clock.h"
+#include "closure.h"
+
+/**************************************************************/
+/* Constants                                                  */
+/**************************************************************/
+
+extern const NAT red_USABLE;
+extern const NAT red_WORKEDOFF;
+extern const NAT red_ALL;
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+static __inline__ BOOL red_WorkedOffMode(NAT Mode)
+{
+  return (Mode == red_WORKEDOFF || Mode == red_ALL);
+}
+
+static __inline__ BOOL red_OnlyWorkedOffMode(NAT Mode)
+{
+  return (Mode == red_WORKEDOFF);
+}
+
+static __inline__ BOOL red_UsableMode(NAT Mode)
+{
+  return (Mode == red_USABLE || Mode == red_ALL);
+}
+
+static __inline__ BOOL red_AllMode(NAT Mode)
+{
+  return (Mode == red_ALL);
+}
+
+
+void   red_Init(void);        
+
+
+LIST   red_CompleteReductionOnDerivedClauses(PROOFSEARCH, LIST, NAT, int, NAT, int*);
+CLAUSE red_ReductionOnDerivedClause(PROOFSEARCH, CLAUSE, NAT);
+CLAUSE red_CompleteReductionOnDerivedClause(PROOFSEARCH, CLAUSE, NAT);
+LIST   red_BackReduction(PROOFSEARCH, CLAUSE, NAT);
+LIST   red_SatUnit(PROOFSEARCH, LIST);
+LIST   red_SatInput(PROOFSEARCH);
+LIST   red_ReduceInput(PROOFSEARCH, LIST);
+BOOL   red_ClauseDeletion(SORTTHEORY, CLAUSE, FLAGSTORE, PRECEDENCE);
+
+
+void   red_CheckSplitSubsumptionCondition(PROOFSEARCH);
+
+
+#endif
diff --git a/test/spass/rules-sort.c b/test/spass/rules-sort.c
new file mode 100644
index 0000000000000000000000000000000000000000..74f8c9f9a154aa3d63e2e25351cf3f8a5cbe4973
--- /dev/null
+++ b/test/spass/rules-sort.c
@@ -0,0 +1,1763 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *           INFERENCE RULES FOR SORTS                    * */
+/* *                                                        * */
+/* *  $Module:   SORTRULES                                  * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "rules-sort.h"
+
+     
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/ 
+
+static LIST inf_GetForwardPartnerLits(LITERAL, st_INDEX);
+static SORT inf_GetSortFromLits(LIST, SORTTHEORY);
+
+
+static BOOL inf_SubsortPrecheck(CLAUSE Clause, LIST TLits, LITERAL Special,
+				st_INDEX Index, SORTTHEORY SortTheory)
+/**************************************************************
+  INPUT:   A clause, a list of constraint literal indices in
+           that clause, a special literal, an index of clauses,
+	   and the actual sort theory.
+  RETURNS: TRUE, if there exists any subsort of the <TLits> sort.
+***************************************************************/
+{
+  SORT tSort, unifierSort;
+  LIST unifiers;
+  BOOL result;
+
+  unifiers = inf_GetForwardPartnerLits(clause_GetLiteral(Clause,(int)list_Car(TLits)),
+				       Index);
+  unifierSort = inf_GetSortFromLits(unifiers, SortTheory);
+  list_Delete(unifiers);
+
+  tSort = sort_TopSort();
+  for (; !list_Empty(TLits); TLits = list_Cdr(TLits)) {
+    TERM actAtom = clause_GetLiteralAtom(Clause, (int)list_Car(TLits));
+    tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(actAtom)),
+			   tSort);
+  }
+  tSort = list_PointerDeleteDuplicates(tSort);
+
+  if (Special == NULL)
+    result = sort_TheoryIsSubsortOf(SortTheory, unifierSort, tSort);
+  else {
+    SORT extraSort;
+    extraSort = sort_TheorySortOfSymbol(SortTheory, clause_LiteralPredicate(Special));
+    result    = sort_TheoryIsSubsortOfExtra(SortTheory, extraSort, unifierSort, tSort);
+    sort_Delete(extraSort);
+  }
+
+  sort_Delete(tSort);
+  sort_Delete(unifierSort);
+
+  return result;
+}
+     
+static LIST inf_GetSortResolutionPartnerLits(TERM Atom, st_INDEX Index)
+/**************************************************************
+  INPUT:   A clause, and an Index of clauses.
+  RETURNS: A list of literals with which sortresolution is possible.
+  MEMORY:  Allocates memory for the list.
+***************************************************************/
+{
+  LIST    Result, TermList, LitScan;
+  LITERAL NextLit;
+  CLAUSE  Clause;
+
+#ifdef CHECK  
+  if (!term_IsAtom(Atom)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_GetSortResolutionPartnerLits: Variable as atom input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Result   = list_Nil();
+  TermList = st_GetUnifier(cont_LeftContext(), Index, cont_RightContext(), Atom);
+  
+  for ( ; !list_Empty(TermList); TermList = list_Pop(TermList)) {
+    
+    if (term_IsAtom(list_Car(TermList))) {
+      
+      for (LitScan = sharing_NAtomDataList(list_Car(TermList)); 
+	   !list_Empty(LitScan); 
+	   LitScan = list_Cdr(LitScan)){
+	NextLit = list_Car(LitScan);
+	Clause  = clause_LiteralOwningClause(NextLit);
+	
+	if (clause_LiteralIsPositive(NextLit) && 
+	    clause_LiteralGetFlag(NextLit,STRICTMAXIMAL) &&
+	    clause_GetFlag(Clause, WORKEDOFF) &&
+	    clause_HasSolvedConstraint(Clause) &&
+	    !list_PointerMember(Result, NextLit)) 
+	  Result = list_Cons(NextLit, Result);
+      }
+    }
+  }
+  
+  return Result;
+}
+
+
+static CLAUSE inf_BuildConstraintHyperResolvent(CLAUSE Clause, LIST Lits,
+						SUBST Subst, LIST Foundlits,
+						FLAGSTORE Flags,
+						PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A <Clause> where the sort constraint is resolved,
+           a list <Lits> of constraint indices in <Clause> where
+	   all corresponding constraints have the same term,
+	   the overall substitution <Subst>,
+	   a list <Foundlits> of literals of found partner clauses,
+	   a flag store and a precedence.
+  RETURNS: A clause, the resolvent of a resolution step.
+***************************************************************/
+{
+  CLAUSE NewClause, ClauseCopy;
+  LIST   Constraint, Antecedent, Succedent, ParentCls, ParentLits, Scan;
+  TERM   Atom;
+  SYMBOL MaxVar,MaxCand;
+  int    i,bound, depth;
+  BOOL   IsFromEmptySort;
+  LIST   Partners;
+  
+  ParentCls   = list_Nil();
+  ParentLits  = list_Nil();
+  Constraint  = list_Nil();
+  Antecedent  = list_Nil();
+  Succedent   = list_Nil();
+  Partners    = list_Nil();
+  depth       = clause_Depth(Clause);
+
+  for (Scan=Foundlits; !list_Empty(Scan); Scan=list_Cdr(Scan))
+    depth = misc_Max(depth,
+		     clause_Depth(clause_LiteralOwningClause(list_Car(Scan))));
+
+  ClauseCopy  = clause_Copy(Clause);
+  Partners    = list_Cons(ClauseCopy, Partners);
+  clause_SubstApply(Subst, ClauseCopy);
+
+  IsFromEmptySort = term_IsVariable(term_FirstArgument(
+    clause_GetLiteralAtom(Clause, (int)list_Car(Lits))));
+
+  bound = clause_LastConstraintLitIndex(ClauseCopy);
+
+  for (i = clause_FirstLitIndex(); i <= bound; i++)
+    if (!list_PointerMember(Lits, (POINTER)i)) {
+      Atom  = term_Copy(clause_GetLiteralAtom(ClauseCopy, i));
+      Constraint = list_Cons(Atom, Constraint);
+    } 
+    else {
+      ParentCls  = list_Cons((POINTER)clause_Number(ClauseCopy), ParentCls);
+      ParentLits = list_Cons((POINTER)i, ParentLits);
+    }
+
+  bound = clause_LastAntecedentLitIndex(ClauseCopy);
+  for ( ; i <= bound; i++) {
+    Atom = term_Copy(clause_GetLiteralAtom(ClauseCopy, i));
+    Antecedent = list_Cons(Atom, Antecedent);
+  }
+  bound = clause_LastSuccedentLitIndex(ClauseCopy);
+  for (; i <= bound; i++) {
+    Atom = term_Copy(clause_GetLiteralAtom(ClauseCopy, i));
+    Succedent = list_Cons(Atom, Succedent);
+  }
+  bound = clause_LastConstraintLitIndex(Clause);
+  for (i = clause_FirstLitIndex(); i <= bound; i++) {			
+    /* Hier sollen die gematchten Constraintliterale dazu fuehren, dass die */
+    /* c,a und s- literale der Partnerclauses in die Listen kommen...       */
+
+    if (list_PointerMember(Lits, (POINTER)i)) {
+      CLAUSE  PartnerCopy;
+      LITERAL PLit;
+      TERM    PAtom;
+      SUBST   NewSubst,RightSubst;
+      int     j,lc,la,n,PLitInd;
+
+      Atom      = clause_GetLiteralAtom(ClauseCopy, i);
+      NewClause = clause_CreateUnnormalized(Constraint, Antecedent, Succedent);
+
+      list_Delete(Constraint);
+      list_Delete(Antecedent);
+      list_Delete(Succedent);
+      Constraint  = list_Nil();
+      Antecedent  = list_Nil();
+      Succedent   = list_Nil();
+
+      /* Find corresponding Foundlit: */
+      for (Scan = Foundlits; 
+	   term_TopSymbol(Atom) !=
+	     term_TopSymbol(clause_LiteralAtom(list_Car(Scan))); 
+	   Scan = list_Cdr(Scan));
+      PLit        = list_Car(Scan);
+      PLitInd     = clause_LiteralGetIndex(PLit);
+      PartnerCopy = clause_Copy(clause_LiteralOwningClause(PLit));
+      Partners    = list_Cons(PartnerCopy, Partners);
+      ParentCls   = list_Cons((POINTER)clause_Number(PartnerCopy), ParentCls);
+      ParentLits  = list_Cons((POINTER)PLitInd, ParentLits);
+      MaxVar      = clause_SearchMaxVar(ClauseCopy);
+      MaxCand     = clause_SearchMaxVar(NewClause);
+      MaxVar      = ((MaxVar > MaxCand) ? MaxVar : MaxCand);   
+      /* MaxVar is the maximal variable in the new clause or the ClauseCopy, */
+      /* the latter to guarantee the stability of variable names.            */
+
+      clause_RenameVarsBiggerThan(PartnerCopy, MaxVar);
+      PLit  = clause_GetLiteral(PartnerCopy, PLitInd);
+      PAtom = clause_LiteralAtom(PLit);
+      
+      cont_Check();
+      if (!unify_UnifyNoOC(cont_LeftContext(), PAtom, cont_RightContext(), Atom)) {
+	misc_StartErrorReport();
+	misc_ErrorReport("\n In inf_BuildConstraintHyperResolvent: Unification failed.");
+	misc_FinishErrorReport();
+      }
+      subst_ExtractUnifier(cont_LeftContext(), &RightSubst, cont_RightContext(), &NewSubst);
+      cont_Reset();
+
+      clause_SubstApply(NewSubst, NewClause);
+      clause_SubstApply(NewSubst, ClauseCopy);
+      subst_Delete(NewSubst);
+      
+      n  = clause_Length(PartnerCopy);
+      lc = clause_LastConstraintLitIndex(PartnerCopy);
+      la = clause_LastAntecedentLitIndex(PartnerCopy);
+      for (j = clause_FirstLitIndex(); j < n; j++) {
+	if (j <= lc) 
+	  Constraint  = list_Cons(subst_Apply(RightSubst,
+	    term_Copy(clause_GetLiteralAtom(PartnerCopy, j))),
+	      Constraint);
+	else if (j <= la) 
+	  Antecedent  = list_Cons(subst_Apply(RightSubst,
+            term_Copy(clause_GetLiteralAtom(PartnerCopy, j))),
+               Antecedent);
+	else if (j != PLitInd)
+	  Succedent  = list_Cons(subst_Apply(RightSubst,
+            term_Copy(clause_GetLiteralAtom(PartnerCopy, j))),
+               Succedent);
+      }
+
+      subst_Delete(RightSubst);
+      
+      n  = clause_Length(NewClause);
+      lc = clause_LastConstraintLitIndex(NewClause);
+      la = clause_LastAntecedentLitIndex(NewClause);
+      
+      for (j = clause_FirstLitIndex(); j < n; j++) {
+	if (j <= lc) 
+	  Constraint  = list_Cons(term_Copy(clause_GetLiteralAtom(NewClause, j)),
+				  Constraint);
+	else if (j <= la) 
+	  Antecedent  = list_Cons(term_Copy(clause_GetLiteralAtom(NewClause, j)),
+				  Antecedent);
+	else 
+	  Succedent  = list_Cons(term_Copy(clause_GetLiteralAtom(NewClause, j)),
+				 Succedent);
+      }      
+      clause_Delete(NewClause);
+      clause_DecreaseCounter();
+    }
+  }
+  NewClause = clause_Create(Constraint, Antecedent, Succedent, Flags,Precedence);
+
+  list_Delete(Constraint); 
+  list_Delete(Antecedent); 
+  list_Delete(Succedent); 
+
+  if (IsFromEmptySort)
+    clause_SetFromEmptySort(NewClause);
+  else
+    clause_SetFromSortResolution(NewClause);
+
+  clause_SetDepth(NewClause, depth + 1);
+
+  clause_SetSplitDataFromList(NewClause, Partners);
+  clause_DeleteClauseList(Partners);
+
+  clause_SetParentClauses(NewClause, list_NReverse(ParentCls));
+  clause_SetParentLiterals(NewClause, list_NReverse(ParentLits));
+
+  return NewClause;
+}
+
+
+static LIST inf_ConstraintHyperResolvents(CLAUSE Clause, LIST Lits,
+					  SUBST Subst, LIST Restlits,
+					  LIST Foundlits, st_INDEX Index,
+					  FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A <Clause> where the sort constraint is resolved,
+           a list <Lits> of constraint indices in <Clause> where
+	   all corresponding constraints have the same term,
+	   the overall substitution <Subst>,
+	   a list <Restlits> of constraint indeces for which
+	   a partner clause is searched with respect to <Index>,
+	   a list <Foundlits> of literals of already found partner clauses,
+	   a flag store and a precedence.
+  RETURNS: The list of possible resolvents.
+***************************************************************/
+{
+  if (list_Empty(Restlits))
+    return list_List(inf_BuildConstraintHyperResolvent(Clause,Lits,Subst,
+						       Foundlits, Flags,
+						       Precedence));
+  else {
+    CLAUSE  PartnerCopy;
+    LITERAL Lit, PLit;
+    LIST    Result, NextLits;
+    TERM    AtomCopy;
+    SUBST   NewSubst, RightSubst, HelpSubst;
+    SYMBOL  MaxVar, MaxCand;
+    int     PLitInd;
+
+    Result   = list_Nil();
+    Lit      = clause_GetLiteral(Clause, (int) list_Car(Restlits));
+    AtomCopy = subst_Apply(Subst, term_Copy(clause_LiteralAtom(Lit)));
+    NextLits = inf_GetSortResolutionPartnerLits(AtomCopy,Index);
+    MaxVar   = clause_MaxVar(Clause);
+    MaxCand  = clause_AtomMaxVar(AtomCopy);
+    MaxVar   = (symbol_GreaterVariable(MaxVar, MaxCand) ? MaxVar : MaxCand);
+      
+    for ( ; !list_Empty(NextLits); NextLits = list_Pop(NextLits)) {
+      PLit        = list_Car(NextLits);
+      PLitInd     = clause_LiteralGetIndex(PLit);
+      Foundlits   = list_Cons(PLit, Foundlits);
+      PartnerCopy = clause_Copy(clause_LiteralOwningClause(PLit));
+
+      clause_RenameVarsBiggerThan(PartnerCopy, MaxVar);
+      PLit        = clause_GetLiteral(PartnerCopy, PLitInd);
+
+      cont_Check();
+      unify_UnifyNoOC(cont_LeftContext(), AtomCopy,
+		      cont_RightContext(), clause_LiteralAtom(PLit));
+      subst_ExtractUnifier(cont_LeftContext(), &NewSubst, cont_RightContext(), &RightSubst);
+      cont_Reset();
+
+      subst_Delete(RightSubst);
+      HelpSubst = NewSubst;
+      NewSubst  = subst_Compose(NewSubst, subst_Copy(Subst));
+
+      Result = list_Nconc(inf_ConstraintHyperResolvents(Clause, Lits, NewSubst,
+							list_Cdr(Restlits),
+							Foundlits, Index, Flags,
+							Precedence),
+			  Result);
+      subst_Delete(NewSubst);
+      subst_Delete(HelpSubst);
+      clause_Delete(PartnerCopy);
+
+      Foundlits = list_Pop(Foundlits);
+    }
+    term_Delete(AtomCopy);
+
+    return Result;
+  }
+}
+
+
+LIST inf_BackwardSortResolution(CLAUSE GivenClause, st_INDEX Index,
+				SORTTHEORY SortTheory, BOOL Precheck,
+				FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause with a solved sort constraint, an index of clauses,
+           a sort theory, a boolean flag indicating whether the subsort
+	   precheck can be applied, a flag store and a precedence.
+  RETURNS: A list of clauses inferred from the GivenClause by
+           SortResolution with the given clause.
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{
+  LIST     result;
+  int      i, ls;
+
+#ifdef CHECK
+  if (!clause_IsClause(GivenClause, Flags, Precedence) ||
+      !clause_HasSolvedConstraint(GivenClause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_BackwardSortResolution: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  result = list_Nil();
+  ls     = clause_LastSuccedentLitIndex(GivenClause);
+
+  for (i = clause_FirstSuccedentLitIndex(GivenClause); i <= ls; i++) {
+    LITERAL pLit;
+    TERM    pAtom;
+
+    pLit  = clause_GetLiteral(GivenClause, i);
+    pAtom = clause_LiteralAtom(pLit);
+
+    if (clause_LiteralGetFlag(pLit,STRICTMAXIMAL) && 
+	clause_LiteralIsSort(pLit)) {
+      LIST termList;
+      termList = st_GetUnifier(cont_LeftContext(),Index,cont_RightContext(),pAtom);
+      
+      for ( ; !list_Empty(termList); termList = list_Pop(termList)){
+	if (term_IsAtom(list_Car(termList)) &&
+	    !term_IsVariable(term_FirstArgument(list_Car(termList)))) {
+
+	  LIST litScan;
+	  litScan = sharing_NAtomDataList(list_Car(termList));
+	  for ( ; !list_Empty(litScan); litScan = list_Cdr(litScan)) {
+	    LITERAL gLit;
+	    CLAUSE gClause;
+	    gLit    = list_Car(litScan);
+	    gClause = clause_LiteralOwningClause(gLit);
+	    if (clause_LiteralGetIndex(gLit) < clause_FirstAntecedentLitIndex(gClause) && 
+		clause_GetFlag(gClause,WORKEDOFF)) {
+	      TERM   gAtom;
+	      int    lc, gi, j;
+	      LIST   tLits, restLits;
+	      gAtom     = clause_LiteralAtom(gLit);
+	      lc        = clause_LastConstraintLitIndex(gClause);
+	      gi        = clause_LiteralGetIndex(gLit);
+	      tLits     = list_List((POINTER)gi);
+	      restLits  = list_Nil();
+	      for (j = clause_FirstLitIndex(); j <= lc; j++) {
+		LITERAL tCand;
+		tCand = clause_GetLiteral(gClause, j);
+		if (j != gi &&
+		    term_FirstArgument(clause_LiteralAtom(tCand))
+		    == term_FirstArgument(gAtom)) {
+		  tLits     = list_Cons((POINTER)j, tLits);
+		  restLits  = list_Cons((POINTER)j, restLits);
+		}
+	      }
+
+	      if (!Precheck ||
+		  inf_SubsortPrecheck(gClause,tLits,pLit,Index,SortTheory)) {
+		CLAUSE pClauseCopy;
+		SYMBOL minVar;
+		LIST   foundLits;
+		SUBST  leftSubst, rightSubst;
+		pClauseCopy = clause_Copy(GivenClause);
+		minVar      = clause_MaxVar(gClause);
+		foundLits   = list_List(pLit);
+
+		clause_RenameVarsBiggerThan(pClauseCopy, minVar);
+		pAtom = clause_GetLiteralAtom(pClauseCopy, i);
+		/* set, to unify correctly! */
+
+		cont_Check();
+		unify_UnifyNoOC(cont_LeftContext(), gAtom, cont_RightContext(), pAtom);
+		subst_ExtractUnifier(cont_LeftContext(), &leftSubst,
+				     cont_RightContext(), &rightSubst);
+		cont_Reset();
+
+		subst_Delete(rightSubst);
+
+		result =
+		  list_Nconc(inf_ConstraintHyperResolvents(gClause, tLits,
+							   leftSubst, restLits,
+							   foundLits, Index,
+							   Flags, Precedence),
+			     result);
+
+		pAtom = clause_LiteralAtom(pLit);
+
+		subst_Delete(leftSubst);
+		list_Delete(foundLits);
+		clause_Delete(pClauseCopy);
+	      } /* if Precheck */
+	      list_Delete(tLits);
+	      list_Delete(restLits);
+	    }
+	  }
+	}
+      }
+    }
+  }
+  return result;
+}
+
+
+LIST inf_ForwardSortResolution(CLAUSE GivenClause, st_INDEX Index,
+			       SORTTHEORY SortTheory, BOOL Precheck,
+			       FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause with an unsolved sort constraint, an index of clauses,
+           a sort theory, a boolean flag indicating whether the subsort
+	   precheck can be applied, a flag store and a precedence.
+  RETURNS: A list of clauses inferred from the GivenClause by
+           SortResolution on the given clause.
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{
+  LIST Result, TLits, RestLits;
+  int  i, j, lc;
+  BOOL Hit;
+  TERM TAtom;
+
+#ifdef CHECK
+  if (!clause_IsClause(GivenClause, Flags, Precedence) ||
+      !clause_HasTermSortConstraintLits(GivenClause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_ForwardSortResolution: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Result = list_Nil();
+  lc     = clause_LastConstraintLitIndex(GivenClause);
+  Hit    = FALSE;
+
+  i = clause_FirstLitIndex();
+  while (i <= lc && !Hit) {
+    TAtom = clause_GetLiteralAtom(GivenClause, i);
+    if (!term_IsVariable(term_FirstArgument(TAtom)))
+      Hit = TRUE;
+    else
+      i++;
+  }
+
+  if (!Hit)
+    return list_Nil();
+
+  /* added because of compiler warnings */
+  TAtom = clause_GetLiteralAtom(GivenClause, i);
+
+  /* Search the other T_i from <GivenClause> */
+  TLits    = list_List((POINTER)i);
+  for (j = i+1; j <= lc; j++) {
+    if (term_FirstArgument(clause_GetLiteralAtom(GivenClause, j))
+	== term_FirstArgument(TAtom))
+      TLits    = list_Cons((POINTER)j, TLits);
+  }
+  RestLits = list_Copy(TLits);
+  
+  if (!Precheck ||
+      inf_SubsortPrecheck(GivenClause, TLits, NULL, Index, SortTheory)) {
+
+    Result = inf_ConstraintHyperResolvents(GivenClause, TLits, subst_Nil(),
+					   RestLits, list_Nil(), Index, Flags,
+					   Precedence);
+
+  }
+  list_Delete(RestLits);
+  list_Delete(TLits);
+
+  return Result;
+}
+
+
+LIST inf_BackwardEmptySort(CLAUSE GivenClause, st_INDEX Index,
+			   SORTTHEORY SortTheory, BOOL Precheck,
+			   FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause with a solved sort constraint, an 'Index' of clauses,
+           a sort theory, a boolean flag indicating whether the subsort
+	   precheck can be applied, a flag store and a precedence.
+  RETURNS: A list of clauses inferred from the GivenClause by
+           EmptySort with the given clause.
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{
+  LIST result;
+  int  i, ls;
+
+#ifdef CHECK
+  if (!(clause_IsClause(GivenClause, Flags, Precedence)) ||
+      !clause_HasSolvedConstraint(GivenClause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_BackwardEmptySort: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  result = list_Nil();
+  
+  ls = clause_LastSuccedentLitIndex(GivenClause);
+
+  for (i = clause_FirstSuccedentLitIndex(GivenClause); i <= ls; i++) {
+    LITERAL pLit  = clause_GetLiteral(GivenClause, i);
+    TERM    pAtom = clause_LiteralAtom(pLit);
+      
+    if (clause_LiteralGetFlag(pLit,STRICTMAXIMAL) && 
+	clause_LiteralIsSort(pLit)) {
+      LIST unifiers = st_GetUnifier(cont_LeftContext(),Index,cont_RightContext(),pAtom);
+	
+      for ( ; !list_Empty(unifiers); unifiers = list_Pop(unifiers)){
+	if (term_IsAtom(list_Car(unifiers)) &&
+	    term_IsVariable(term_FirstArgument(list_Car(unifiers)))) {
+	  LIST litScan = sharing_NAtomDataList(list_Car(unifiers));
+	    
+	  for ( ; !list_Empty(litScan); litScan = list_Cdr(litScan)){
+	    LITERAL gLit   = list_Car(litScan);
+	    CLAUSE gClause = clause_LiteralOwningClause(gLit);
+	      
+	    if (clause_LiteralGetIndex(gLit) < clause_FirstAntecedentLitIndex(gClause) &&
+		clause_GetFlag(gClause,WORKEDOFF) &&
+		clause_HasOnlyVarsInConstraint(gClause, Flags, Precedence)) {
+	      TERM   gAtom     = clause_LiteralAtom(gLit);
+	      SYMBOL var       = term_TopSymbol(term_FirstArgument(gAtom));
+	      int    lc        = clause_LastConstraintLitIndex(gClause);
+	      int    gi        = clause_LiteralGetIndex(gLit);
+	      BOOL   varOccursNoMore;
+	      int    j, bound;
+
+	      varOccursNoMore = TRUE;
+	      bound           = clause_LastSuccedentLitIndex(gClause);
+		
+	      for (j = clause_FirstAntecedentLitIndex(gClause);
+		   (j <= bound) && varOccursNoMore;
+		   j++) {
+		if (term_ContainsSymbol(clause_GetLiteralAtom(gClause, j), var))
+		  varOccursNoMore = FALSE;
+	      }
+		
+	      if (varOccursNoMore) {
+		LIST tLits, restLits;
+
+		/* Search the other T_i from <gClause> */
+		tLits     = list_List((POINTER)gi);
+		restLits  = list_Nil();		
+		for (j = clause_FirstLitIndex(); j <= lc; j++) {
+		  LITERAL tCand = clause_GetLiteral(gClause, j);
+
+		  if (j != gi &&
+		      term_FirstArgument(clause_LiteralAtom(tCand))
+		      == term_FirstArgument(gAtom)) {
+		    tLits     = list_Cons((POINTER)j, tLits);
+		    restLits  = list_Cons((POINTER)j, restLits);
+		  }
+		}
+
+		if (!Precheck ||
+		    inf_SubsortPrecheck(gClause,tLits,pLit,Index,SortTheory)) {
+		  CLAUSE pCopy     = clause_Copy(GivenClause);
+		  SYMBOL minVar    = clause_MaxVar(gClause);
+		  LIST   foundLits = list_List(pLit);
+		  SUBST  leftSubst, rightSubst;
+
+		  clause_RenameVarsBiggerThan(pCopy, minVar);
+		  pAtom = clause_GetLiteralAtom(pCopy, i);
+		  /* set, to adress the renamed term! */
+		  
+		  cont_Check();
+		  unify_UnifyNoOC(cont_LeftContext(), gAtom, cont_RightContext(), pAtom);
+		  subst_ExtractUnifier(cont_LeftContext(),  &leftSubst,
+				       cont_RightContext(), &rightSubst);
+		  cont_Reset();
+
+		  subst_Delete(rightSubst);
+		  
+		  result =
+		    list_Nconc(inf_ConstraintHyperResolvents(gClause, tLits,
+							     leftSubst,restLits,
+							     foundLits, Index,
+							     Flags, Precedence),
+			       result);
+
+		  list_Delete(foundLits);
+		  subst_Delete(leftSubst);
+		  clause_Delete(pCopy);
+		  
+		  pAtom = clause_LiteralAtom(pLit);
+		  /* reset to original clauses literal! */
+		} /* if Precheck */
+		list_Delete(tLits);
+		list_Delete(restLits);
+	      }
+	    }
+	  }
+	}
+      }
+    }
+  }
+  return result;
+}
+
+
+LIST inf_ForwardEmptySort(CLAUSE GivenClause, st_INDEX Index,
+			  SORTTHEORY SortTheory, BOOL Precheck, FLAGSTORE Flags,
+			  PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, an index of clauses, a sort theory,
+           a boolean flag indicating whether the subsort
+	   precheck can be applied, a flag store and a precedence.
+	   The constraint of <GivenClause> is necessarily unsolved
+  RETURNS: A list of clauses inferred from the GivenClause by
+           EmptySort on the given clause.
+  MEMORY:  A list of clauses is produced, where memory for the list
+           and the clauses is allocated.
+***************************************************************/
+{
+  LIST   Result, TLits, RestLits;
+  int    i, j, lc, ls;
+  BOOL   Hit;
+  TERM   TAtom;
+  SYMBOL Var;
+
+#ifdef CHECK
+  if (clause_HasTermSortConstraintLits(GivenClause) ||
+      clause_HasSolvedConstraint(GivenClause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_ForwardEmptySort: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  Result = list_Nil();
+  lc     = clause_LastConstraintLitIndex(GivenClause);
+  Hit    = FALSE;
+  
+  i = clause_FirstLitIndex();
+  while (i <= lc && !Hit) {
+    TAtom = clause_GetLiteralAtom(GivenClause, i);
+
+    if (term_IsVariable(term_FirstArgument(TAtom))) {
+      Var   = term_TopSymbol(term_FirstArgument(TAtom));
+      ls    = clause_LastSuccedentLitIndex(GivenClause);
+      Hit = TRUE;
+      /* Check if the variable occurs in antecedent or succedent literals */
+      for (j = clause_FirstAntecedentLitIndex(GivenClause);
+	   j <= ls && Hit; j++) {
+	if (term_ContainsSymbol(clause_GetLiteralAtom(GivenClause,j), Var))
+	  Hit = FALSE; /* Variable occurs in antecedent/constraint literal */
+      }
+    }
+    if (!Hit)
+      i++;
+  }
+  
+  if (!Hit)
+    return list_Nil();
+
+  TAtom = clause_GetLiteralAtom(GivenClause, i);
+  Var   = term_TopSymbol(term_FirstArgument(TAtom));
+
+  /* Search the other T_i(t) literals */
+  TLits    = list_List((POINTER)i);
+  for (j = i+1; j <= lc; j++) {
+    TERM TCand;
+    
+    TCand = clause_GetLiteralAtom(GivenClause, j);
+    
+    if (symbol_Equal(term_TopSymbol(term_FirstArgument(TCand)), Var))
+      TLits    = list_Cons((POINTER)j, TLits);
+  }
+  RestLits = list_Copy(TLits);
+  
+  if (!Precheck ||
+      inf_SubsortPrecheck(GivenClause, TLits, NULL, Index, SortTheory)) {
+    
+    Result = inf_ConstraintHyperResolvents(GivenClause, TLits, subst_Nil(),
+					   RestLits, list_Nil(), Index, Flags,
+					   Precedence);
+
+  }
+  list_Delete(RestLits);
+  list_Delete(TLits);
+  
+  return Result;
+}
+
+static LIST inf_GetForwardPartnerLits(LITERAL Literal, st_INDEX Index)
+/**************************************************************
+  INPUT:   A monadic literal, and an index of clauses.
+  RETURNS: A list of monadic succedent literals whose subterm
+           is unifiable with the (one) subterm of <Literal>.
+	   The literals are strict maximal in their respective clauses,
+	   the clauses are "WORKEDOFF" and either the subterm
+	   is not a variable or the clause has an empty constraint.
+  MEMORY:  Allocates memory for the list.
+***************************************************************/
+{
+  LIST result, unifiers, atomScan, litScan;
+
+#ifdef CHECK
+  if (!clause_LiteralIsLiteral(Literal) || !clause_LiteralIsSort(Literal)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_GetForwardPartnerLits: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  result   = list_Nil();
+  /* Search unifiers for the literal's subterm */
+  unifiers = st_GetUnifier(cont_LeftContext(), Index, cont_RightContext(),
+			   term_FirstArgument(clause_LiteralAtom(Literal)));
+  
+  for ( ; !list_Empty(unifiers); unifiers = list_Pop(unifiers)) {
+
+    if (!term_IsAtom(list_Car(unifiers))) { /* Can happen if arg is variable */
+      
+      for (atomScan = term_SupertermList(list_Car(unifiers)); 
+	   !list_Empty(atomScan); 
+	   atomScan = list_Cdr(atomScan)) {
+	TERM atomCand;
+	atomCand = (TERM) list_Car(atomScan);
+	if (term_IsDeclaration(atomCand)) {
+	  /* We are looking for an unary atom */
+
+	  for (litScan = sharing_NAtomDataList(atomCand);
+	       !list_Empty(litScan);
+	       litScan = list_Cdr(litScan)) {
+	    LITERAL nextLit;
+	    CLAUSE  nextClause;
+	    nextLit    = list_Car(litScan);
+	    nextClause = clause_LiteralOwningClause(nextLit);
+
+	    if (clause_LiteralIsPositive(nextLit) && 
+		clause_LiteralGetFlag(nextLit,STRICTMAXIMAL) &&
+		clause_GetFlag(nextClause, WORKEDOFF) &&
+		(!term_IsVariable(list_Car(unifiers)) ||
+		 clause_HasEmptyConstraint(nextClause)) &&
+		clause_HasSolvedConstraint(nextClause)) {
+	      /* Add the literal from the copied clause */
+	      result = list_Cons(nextLit, result);
+	    }
+	  }  /* litScan */
+	}    /* if IsAtom */
+      }      /* atomScan */
+    }        /* ! variable */
+  }          /* unifiers */
+  return result;
+}
+
+static BOOL inf_LiteralsHaveSameSubtermAndAreFromSameClause(LITERAL L1, LITERAL L2)
+/**************************************************************
+  INPUT:   Two literals.
+  RETURNS: TRUE, if both literals have the same term and are
+           from the same clause, FALSE otherwise.
+	   Since both literals are shared, pointer equality
+	   is used to detect this.
+	   This function is used by inf_GetBackwardPartnerLits().
+***************************************************************/
+{
+  return (term_FirstArgument(clause_LiteralAtom(L1))
+	  == term_FirstArgument(clause_LiteralAtom(L2)) &&
+	  clause_LiteralOwningClause(L1) == clause_LiteralOwningClause(L2));
+}
+
+static void inf_GetBackwardPartnerLits(LITERAL Literal, st_INDEX Index,
+				       LIST* ConstraintLits, LIST* Unifiers,
+				       BOOL IsFromEmptySort, FLAGSTORE Flags,
+				       PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A literal, an index of clauses, two pointers to lists,
+           a boolean value, a flag store and a precedence.
+  RETURNS:
+  MEMORY:  Allocates memory for the list.
+***************************************************************/
+{
+  LIST candidates, atomScan, litScan;
+  LITERAL nextLit;
+  CLAUSE  nextClause;
+
+#ifdef CHECK
+  if (!clause_LiteralIsLiteral(Literal) || !clause_LiteralIsSort(Literal)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_GetBackwardPartnerLits: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  candidates = st_GetUnifier(cont_LeftContext(), Index, cont_RightContext(),
+			     term_FirstArgument(clause_LiteralAtom(Literal)));
+
+  for ( ; !list_Empty(candidates); candidates = list_Pop(candidates)) {
+    if (!term_IsAtom(list_Car(candidates))) { /* May happen if arg is variable */
+      /* Consider variable unifiers only if called from BackwardEmptySort */
+      for (atomScan = term_SupertermList(list_Car(candidates)); 
+	   !list_Empty(atomScan); 
+	   atomScan = list_Cdr(atomScan)) {
+	TERM atomCand;
+	atomCand = (TERM) list_Car(atomScan);
+	if (term_IsDeclaration(atomCand)) {
+	  /* We are looking for unary atoms */
+
+	  for (litScan = sharing_NAtomDataList(atomCand);
+	       !list_Empty(litScan);
+	       litScan = list_Cdr(litScan)) {
+	    nextLit    = list_Car(litScan);
+	    nextClause = clause_LiteralOwningClause(nextLit);
+	    
+	    if (clause_GetFlag(nextClause, WORKEDOFF)) {
+	      if (clause_LiteralIsPositive(nextLit)) {
+		if (clause_LiteralGetFlag(nextLit,STRICTMAXIMAL) &&
+		    (!term_IsVariable(list_Car(candidates)) ||
+		     clause_HasEmptyConstraint(nextClause)) &&
+		    clause_HasSolvedConstraint(nextClause) &&
+		    !symbol_Equal(clause_LiteralPredicate(Literal),
+				  clause_LiteralPredicate(nextLit))) {
+		  /* Don't consider literals with same top symbol as given literal */
+		  /* since the given clause must be part of any inference */
+		  *Unifiers = list_Cons(nextLit, *Unifiers);
+		}
+	      } else if (clause_LiteralGetIndex(nextLit) < clause_FirstAntecedentLitIndex(nextClause) &&
+			 ((!term_IsVariable(list_Car(candidates)) && !IsFromEmptySort) ||
+			  (term_IsVariable(list_Car(candidates)) && IsFromEmptySort &&
+			   clause_HasOnlyVarsInConstraint(nextClause,Flags, Precedence)))) {
+		*ConstraintLits = list_Cons(nextLit, *ConstraintLits);
+	      }
+	    }
+	  } /* litScan */
+	}
+      }     /* atomScan */
+    }
+  }         /* candidates */
+
+  /* We have to avoid constraint literals from the same clause with the same
+     term or variable, since those would create the same result clause. */
+  *ConstraintLits =
+    list_DeleteDuplicates(*ConstraintLits,
+			  (BOOL (*)(POINTER,POINTER)) inf_LiteralsHaveSameSubtermAndAreFromSameClause);
+}
+
+static void inf_MakeClausesDisjoint(CLAUSE GClause, LIST Literals)
+/**************************************************************
+  INPUT:   A clause and a non-empty list of literals.
+  EFFECT:  All input clauses, those pointed to by the literals,
+           are variable disjointly renamed.
+***************************************************************/
+{
+  SYMBOL maxVar, maxCand;
+  CLAUSE lastClause;
+
+  maxVar     = clause_MaxVar(GClause);
+  lastClause = clause_LiteralOwningClause(list_Car(Literals));
+  clause_RenameVarsBiggerThan(lastClause, maxVar);
+  Literals   = list_Cdr(Literals);
+
+  for ( ; !list_Empty(Literals); Literals = list_Cdr(Literals)) {
+    CLAUSE actClause;
+
+    clause_UpdateMaxVar(lastClause);
+    maxCand = clause_MaxVar(lastClause);    
+    maxVar = (symbol_GreaterVariable(maxVar,maxCand)? maxVar : maxCand);
+
+    actClause = clause_LiteralOwningClause(list_Car(Literals));
+    clause_RenameVarsBiggerThan(actClause, maxVar);
+  }
+}
+
+static void inf_CopyUnifierClauses(LIST Literals)
+/**************************************************************
+  INPUT:   A list of literals.
+  EFFECT:  Replaces all literals by pointers to literals of copies
+           of the respective clauses.
+***************************************************************/
+{
+  for ( ; !list_Empty(Literals); Literals = list_Cdr(Literals)) {
+    CLAUSE actClause;
+    int    i;
+
+    actClause = clause_LiteralOwningClause(list_Car(Literals));
+    i         = clause_LiteralGetIndex(list_Car(Literals));
+    actClause = clause_Copy(actClause);
+    list_Rplaca(Literals, clause_GetLiteral(actClause, i)); /* Set to literal from copy */
+  }
+}
+
+static void inf_DeleteUnifierClauses(LIST Literals)
+/**************************************************************
+  INPUT:   A list of literals.
+  EFFECT:  Deletes all clauses the literals point to.
+***************************************************************/
+{
+  for ( ; !list_Empty(Literals); Literals = list_Cdr(Literals)) {
+    clause_Delete(clause_LiteralOwningClause(list_Car(Literals)));
+    list_Rplaca(Literals, NULL);
+  }
+}
+
+static SORT inf_GetSortFromLits(LIST Literals, SORTTHEORY SortTheory)
+/**************************************************************
+  INPUT:   A list of literals and a sort theory.
+  RETURNS: The sort created from the literals' predicates.
+***************************************************************/
+{
+  SORT result = sort_TopSort();
+
+  for ( ; !list_Empty(Literals); Literals = list_Cdr(Literals)) {
+    SORT newSort = sort_TheorySortOfSymbol(SortTheory,
+					   clause_LiteralPredicate(list_Car(Literals)));
+    
+    result = sort_Intersect(newSort, result);
+  }
+
+  list_PointerDeleteDuplicates(result);
+
+  return result;
+}
+
+static LIST inf_ApplyWeakening(CLAUSE Clause, LIST TLits, LIST Partners,
+			       CONDITION Condition, FLAGSTORE Flags,
+			       PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, a list of constraint indices in <Clause>,
+           a list of maximal, monadic succedent literals,
+	   a subsort condition, a flag store and a precedence.
+  RETURNS: A one-element list with a clause derived from the
+           clause and the partner clauses by the Weakening or
+	   Empty Sort rule.
+           The flag store is needed to create the result clause.
+  MEMORY:  Memory is allocated for the returned list and the clause.
+***************************************************************/
+{
+  LIST   scan, parents;
+  LIST   constraint, antecedent, succedent;
+  LIST   parentClauses, parentLits;   /* clause numbers and literal indices */
+  int    i, bound, depth;
+  TERM   tSubterm;
+  CLAUSE newClause;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence) || list_Empty(TLits) ||
+      list_Empty(Partners) || Condition == NULL) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_ApplyWeakening: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  constraint    = antecedent = succedent = list_Nil();
+  parentClauses = parentLits = list_Nil();
+  parents       = list_Nil();                      /* Used to set split data */
+  depth         = clause_Depth(Clause);
+  tSubterm      = term_FirstArgument(clause_GetLiteralAtom(Clause, (int)list_Car(TLits)));
+
+  /* Now collect the literals of the new clause */
+  /* First consider the condition atoms */
+  for (scan=sort_ConditionConstraint(Condition); !list_Empty(scan); scan=list_Cdr(scan)) {
+    TERM termCopy;
+
+    termCopy = term_Copy(list_Car(scan));
+    term_ReplaceVariable(termCopy, sort_ConditionVar(Condition), tSubterm);
+    constraint = list_Cons(cont_CopyAndApplyBindings(cont_LeftContext(), termCopy),
+			   constraint);
+    term_Delete(termCopy);   /* constraint contains a copy */
+  }
+  for (scan=sort_ConditionAntecedent(Condition); !list_Empty(scan); scan=list_Cdr(scan)) {
+    TERM termCopy;
+
+    termCopy = term_Copy(list_Car(scan));
+    term_ReplaceVariable(termCopy, sort_ConditionVar(Condition), tSubterm);
+    antecedent = list_Cons(cont_CopyAndApplyBindings(cont_LeftContext(), termCopy),
+			   antecedent);
+    term_Delete(termCopy);   /* antecedent contains a copy */ 
+  }
+  for (scan=sort_ConditionSuccedent(Condition); !list_Empty(scan); scan=list_Cdr(scan)) {
+    TERM termCopy;
+    
+    termCopy = term_Copy(list_Car(scan));
+    term_ReplaceVariable(termCopy, sort_ConditionVar(Condition), tSubterm);
+    succedent = list_Cons(cont_CopyAndApplyBindings(cont_LeftContext(), termCopy),
+			  succedent);
+    term_Delete(termCopy);   /* succedent contains a copy */
+  }
+  /* update parents and depth from condition clauses */
+  for (scan=sort_ConditionClauses(Condition); !list_Empty(scan); scan=list_Cdr(scan)) {
+    CLAUSE condClause;
+
+    condClause    = list_Car(scan);
+    parents       = list_Cons(condClause, parents);
+    parentClauses = list_Cons((POINTER)clause_Number(condClause), parentClauses);
+    parentLits    = list_Cons((POINTER)clause_FirstSuccedentLitIndex(condClause), parentLits);
+    depth         = misc_Max(depth, clause_Depth(condClause));
+  }
+
+  /* Now we consider the partner clauses */
+  for (scan = Partners; !list_Empty(scan); scan = list_Cdr(scan)) {
+    LITERAL pLit;
+    CLAUSE  pClause;
+    int     pi;
+
+    pLit    = list_Car(scan);
+    pClause = clause_LiteralOwningClause(pLit);
+    pi      = clause_LiteralGetIndex(pLit);
+    bound   = clause_LastConstraintLitIndex(pClause);
+    for (i = clause_FirstLitIndex(); i <= bound; i++) {
+      constraint = list_Cons(cont_CopyAndApplyBindings(cont_RightContext(),
+						       clause_GetLiteralAtom(pClause,i)),
+			     constraint);
+    }
+    bound = clause_LastAntecedentLitIndex(pClause);
+    for (i = clause_FirstAntecedentLitIndex(pClause); i <= bound; i++) {
+      antecedent = list_Cons(cont_CopyAndApplyBindings(cont_RightContext(),
+						       clause_GetLiteralAtom(pClause,i)),
+			     antecedent);
+    }
+    bound = clause_LastSuccedentLitIndex(pClause);
+    for (i = clause_FirstSuccedentLitIndex(pClause); i <= bound; i++) {
+      if (i != pi)
+	succedent = list_Cons(cont_CopyAndApplyBindings(cont_RightContext(),
+							clause_GetLiteralAtom(pClause,i)),
+			      succedent);
+    }
+
+    parents = list_Cons(pClause, parents);
+
+    parentClauses = list_Cons((POINTER)clause_Number(pClause), parentClauses);
+    parentLits    = list_Cons((POINTER) pi, parentLits);
+
+    depth = misc_Max(depth, clause_Depth(pClause));
+  }
+
+  /* Last but not least we consider the <Clause> itself */
+  bound = clause_LastConstraintLitIndex(Clause);
+  for (i = clause_FirstLitIndex(); i <= bound; i++) {
+    if (!list_PointerMember(TLits, (POINTER)i))
+	constraint = list_Cons(cont_CopyAndApplyBindings(cont_LeftContext(),
+							 clause_GetLiteralAtom(Clause,i)),
+			       constraint);
+    else {
+      parentClauses = list_Cons((POINTER)clause_Number(Clause), parentClauses);
+      parentLits    = list_Cons((POINTER)i, parentLits);
+    }
+  }
+  bound = clause_LastAntecedentLitIndex(Clause);
+  for (i = clause_FirstAntecedentLitIndex(Clause); i <= bound; i++) {
+    antecedent = list_Cons(cont_CopyAndApplyBindings(cont_LeftContext(),
+						     clause_GetLiteralAtom(Clause,i)),
+			   antecedent);
+  }
+  bound = clause_LastSuccedentLitIndex(Clause);
+  for (i = clause_FirstSuccedentLitIndex(Clause); i <= bound; i++) {
+    succedent = list_Cons(cont_CopyAndApplyBindings(cont_LeftContext(),
+						    clause_GetLiteralAtom(Clause,i)),
+			  succedent);
+  }
+
+  parents = list_Cons(Clause, parents);
+  
+  /* Now we've got all data we need */
+  newClause = clause_Create(constraint, antecedent, succedent, Flags,Precedence);
+  
+  list_Delete(constraint);
+  list_Delete(antecedent);
+  list_Delete(succedent);
+  
+  if (term_IsVariable(tSubterm))
+    clause_SetFromEmptySort(newClause);
+  else
+    clause_SetFromSortResolution(newClause);
+  
+  clause_SetDepth(newClause, depth+1);
+  clause_SetFlag(newClause, DOCCLAUSE);
+  
+  clause_SetSplitDataFromList(newClause, parents);
+  list_Delete(parents);
+  
+  clause_SetParentClauses(newClause, parentClauses);
+  clause_SetParentLiterals(newClause, parentLits);
+ 
+  return list_List(newClause);
+}
+
+static LIST inf_InternWeakening(CLAUSE Clause, LIST TLits, LIST Unifiers,
+				LITERAL Special, LIST SojuList, FLAGSTORE Flags,
+				PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A <Clause> with unsolved sort constraint,
+           a list <TLits> of constraint indices in <Clause> where
+	   all corresponding constraints have the same term,
+	   a list <Unifiers> of monadic succedent literals whose
+	   subterm is unifiable with the subterm of the <TLits>,
+	   and a flag store.
+	   If called from a backward rule the literal <Special>
+	   will be the succedent literal from the respective
+	   GivenClause, that must be part of every considered
+	   SOJU sort. If called from a forward rule <Special> is NULL.
+	   A list <SojuList> of sort pairs.
+	   A flag store and a precedence.
+  RETURNS: The list of possible resolvents.
+  EFFECT:  ATTENTION: <SojuList> is deleted.
+  MEMORY:  Memory is allocated for the returned list and the clauses.
+***************************************************************/
+{
+  LIST result, myUnifiers;
+  TERM searchTerm; 
+  int  stack;
+
+  LIST scan;
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence) || list_Empty(TLits) ||
+      list_Empty(Unifiers)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_InternWeakening: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  putchar('\n'); clause_Print(Clause);
+  fputs("\nT_k = ", stdout);
+  for (scan = TLits; !list_Empty(scan); scan = list_Cdr(scan)) {
+    clause_LiteralPrint(clause_GetLiteral(Clause, (int)list_Car(scan)));
+    putchar(' ');
+  }
+  fputs("\nS_k =", stdout);
+  for (scan = Unifiers; !list_Empty(scan); scan = list_Cdr(scan)) {
+    putchar('\n');
+    clause_LiteralPrint(list_Car(scan));
+    fputs(" in ", stdout);
+    clause_Print(clause_LiteralOwningClause(list_Car(scan)));
+  }
+  putchar('\n');
+
+  if (list_Empty(SojuList))
+    return list_Nil();
+
+  /*return list_Nil();*/
+  /* Und Schluss */
+
+  result = list_Nil();
+
+  myUnifiers = list_Copy(Unifiers);
+  inf_CopyUnifierClauses(myUnifiers);
+  inf_MakeClausesDisjoint(Clause, myUnifiers);
+
+  searchTerm =
+    term_FirstArgument(clause_GetLiteralAtom(Clause, (int)list_Car(TLits)));
+
+  stack  = stack_Bottom();
+
+  for ( ; !list_Empty(SojuList); SojuList = list_Pop(SojuList)) {
+    SOJU actSoju = list_Car(SojuList);
+
+    fputs("\nSOJU: ", stdout); sort_PairPrint(actSoju); fflush(stdout);
+
+    if (Special == NULL ||
+	sort_ContainsSymbol(sort_PairSort(actSoju),
+			    clause_LiteralPredicate(Special))) { 
+      LIST actSortSymbols, symbolScan, unifierScan, subset;
+
+      actSortSymbols = sort_GetSymbolsFromSort(sort_PairSort(actSoju));
+      subset         = list_Nil();
+
+      symbolScan  = actSortSymbols;
+      unifierScan = myUnifiers;
+
+      do {
+	while (!list_Empty(symbolScan) && !list_Empty(unifierScan)) {
+	  LITERAL actLit = list_Car(unifierScan);
+
+	  if (symbol_Equal(clause_LiteralPredicate(list_Car(unifierScan)),
+			   (SYMBOL)list_Car(symbolScan))) {
+	    cont_StartBinding();
+	    if (unify_UnifyNoOC(cont_LeftContext(), searchTerm, cont_RightContext(),
+				term_FirstArgument(clause_LiteralAtom(actLit)))) {
+	      /* Found corresponding literal for sort symbol */
+	      stack_Push(symbolScan);
+	      stack_Push(list_Cdr(unifierScan));
+	      subset = list_Cons(actLit, subset);
+	      /* Now search literals for the next sort symbol */
+	      symbolScan = list_Cdr(symbolScan);
+
+	      if (!list_Empty(symbolScan))
+		/* Start search for literal at the beginning of unifier list */
+		unifierScan = myUnifiers;
+	      else
+		unifierScan = list_Cdr(unifierScan);
+	    } else {
+	      cont_BackTrack();
+	      unifierScan = list_Cdr(unifierScan);
+	    }
+	  } else
+	    unifierScan = list_Cdr(unifierScan);
+	}
+
+	if (list_Empty(symbolScan)) {
+	  /*putchar('\n');
+	  clause_LiteralListPrint(subset);*/
+	  /* Found subset */
+	  result = list_Nconc(inf_ApplyWeakening(Clause, TLits, subset,
+						 sort_PairCondition(actSoju),
+						 Flags, Precedence),
+			      result);
+	}
+
+	while (!stack_Empty(stack) && list_Empty(stack_Top())) {
+	  /* No more literals */
+	  stack_NPop(2);
+	  cont_BackTrack();
+	  subset = list_Pop(subset);
+	}
+
+	if (!stack_Empty(stack)) {
+	  /* Implies that stack_Top is a non-empty list */
+	  unifierScan = stack_PopResult();
+	  symbolScan  = stack_PopResult();
+	  cont_BackTrack();
+	  subset = list_Pop(subset);
+	}
+      } while (!stack_Empty(stack) || !list_Empty(unifierScan));
+
+      list_Delete(actSortSymbols);
+    }
+    sort_PairDelete(actSoju);
+  } /* For all SOJUs */
+
+  inf_DeleteUnifierClauses(myUnifiers);
+  list_Delete(myUnifiers);
+
+  return result;
+}
+
+LIST inf_ForwardWeakening(CLAUSE GivenClause, st_INDEX Index,
+			  SORTTHEORY SortTheory, FLAGSTORE Flags,
+			  PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, an index of clauses, a sort theory, a flag store
+           and a precedence.
+           The sort constraint of the clause must contain a non-variable term
+	   (this implies the sort constraint is unsolved). 
+  RETURNS: A list of clauses derived from the GivenClause by
+           the Weakening rule.
+  MEMORY:  Memory is allocated for the returned list and the clauses.
+***************************************************************/
+{
+  LIST    result;
+  int     i, lc;
+  BOOL    hit;
+
+#ifdef CHECK
+  if (!clause_HasTermSortConstraintLits(GivenClause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_ForwardWeakening: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  result = list_Nil();
+  lc     = clause_LastConstraintLitIndex(GivenClause);
+  hit    = FALSE;
+
+  for (i = clause_FirstLitIndex(); i <= lc && !hit; i++) {
+    
+    if (!term_IsVariable(term_FirstArgument(clause_GetLiteralAtom(GivenClause, i)))) {
+      /* Condition implies that constraint is unsolved */
+      LITERAL tLit;
+      LIST    unifiers;
+      int     j;
+
+      tLit     = clause_GetLiteral(GivenClause, i);
+      hit      = TRUE; /* Try only the first appropriate constraint literal */
+      unifiers = inf_GetForwardPartnerLits(tLit, Index);
+
+      if (!list_Empty(unifiers)) {
+	TERM tAtom;
+	LIST tLits, sojuList;
+	SORT tSort, unifierSort;
+
+	tAtom = clause_GetLiteralAtom(GivenClause, i);
+
+	/* Search the other T_k(t) in GivenClause */
+	tLits = list_Nil();
+	tSort = sort_TopSort();
+	for (j = lc; j > i; j--) {
+	  TERM actAtom;
+	  actAtom = clause_GetLiteralAtom(GivenClause, j);
+	  if (term_FirstArgument(actAtom) == term_FirstArgument(tAtom)) {
+	    tLits = list_Cons((POINTER)j, tLits);
+	    tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(actAtom)),
+				   tSort);
+	  }
+	}
+	tLits = list_Cons((POINTER)i, tLits);
+	tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(tAtom)),
+			       tSort);
+	list_PointerDeleteDuplicates(tSort);
+	/* Necessary for Christoph's function */
+
+	unifierSort = inf_GetSortFromLits(unifiers, SortTheory);
+	sojuList    = sort_TheoryComputeAllSubsortHits(SortTheory, unifierSort, tSort);
+	sort_Delete(unifierSort);
+	sort_Delete(tSort);
+
+	result =
+	  list_Nconc(inf_InternWeakening(GivenClause, tLits, unifiers, NULL,
+					 sojuList, Flags, Precedence),
+		     result);
+
+	list_Delete(tLits);
+	list_Delete(unifiers);
+      }
+    }
+  }
+  return result;
+}
+
+LIST inf_BackwardWeakening(CLAUSE GivenClause, st_INDEX Index,
+			   SORTTHEORY SortTheory, FLAGSTORE Flags,
+			   PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause with solved sort constraint, an index of clauses,
+           a sort theory, a flag store and a precedence.
+  RETURNS: A list of clauses inferred from the GivenClause by
+           the Weakening rule.
+  MEMORY:  Memory is allocated for the list and the clauses.
+***************************************************************/
+{
+  LIST     result;
+  int      i, ls;
+
+#ifdef CHECK
+  if (!clause_HasSolvedConstraint(GivenClause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_BackwardWeakening: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  result = list_Nil();
+  ls     = clause_LastSuccedentLitIndex(GivenClause);
+
+  for (i = clause_FirstSuccedentLitIndex(GivenClause); i <= ls; i++) {
+    LITERAL sLit;
+    TERM    sAtom;
+
+    sLit  = clause_GetLiteral(GivenClause, i);
+    sAtom = clause_LiteralAtom(sLit);
+    if (clause_LiteralGetFlag(sLit, STRICTMAXIMAL) && 
+	clause_LiteralIsSort(sLit) &&
+	(!term_IsVariable(term_FirstArgument(sAtom)) ||
+	 clause_HasEmptyConstraint(GivenClause))) {
+      LIST unifiers, partners;
+      SORT unifierSort;
+
+      unifiers = partners = list_Nil();
+      inf_GetBackwardPartnerLits(sLit,Index,&partners,&unifiers,FALSE,Flags,
+				 Precedence);
+      unifiers = list_Cons(sLit, unifiers);
+      /* <partners> holds monadic constraint literals */
+      /* <unifiers> holds monadic, maximal succedent literals */
+      unifierSort = inf_GetSortFromLits(unifiers, SortTheory);
+      
+      for ( ; !list_Empty(partners); partners = list_Pop(partners)) {
+	LITERAL tLit;
+	CLAUSE  tClause;
+	TERM    tAtom;
+	int     ti;
+	int     lc;
+	int     j;
+	LIST    tLits, sojuList;
+	SORT    tSort;
+
+	tLit    = list_Car(partners);
+	tClause = clause_LiteralOwningClause(tLit);
+	tAtom   = clause_LiteralAtom(tLit);
+	ti      = clause_LiteralGetIndex(tLit);
+	lc      = clause_LastConstraintLitIndex(tClause);
+
+	/* Search the other T_k(t) in GivenClause */
+	tLits = list_Nil();
+	tSort = sort_TopSort();
+	for (j = lc; j >= clause_FirstLitIndex(); j--) {
+	  TERM actAtom;
+
+	  actAtom = clause_GetLiteralAtom(tClause, j);
+	  if (j != ti &&
+	      term_FirstArgument(actAtom) == term_FirstArgument(tAtom)) {
+	    tLits = list_Cons((POINTER)j, tLits);
+	    tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(actAtom)),
+				   tSort);
+	  }
+	}
+	tLits = list_Cons((POINTER)ti, tLits);
+	tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(tAtom)),
+			       tSort);
+	list_PointerDeleteDuplicates(tSort);
+
+	sojuList = sort_TheoryComputeAllSubsortHits(SortTheory, unifierSort, tSort);
+	sort_Delete(tSort);
+
+	cont_StartBinding();
+	unify_UnifyNoOC(cont_LeftContext(), tAtom,
+			cont_RightContext(), sAtom);
+
+	result =
+	  list_Nconc(inf_InternWeakening(tClause, tLits, unifiers, sLit,
+					 sojuList, Flags, Precedence),
+		     result);
+
+	cont_BackTrack();
+
+	list_Delete(tLits);
+      }
+      sort_Delete(unifierSort);
+      list_Delete(unifiers);
+    }
+  }
+
+  return result;
+}
+
+LIST inf_ForwardEmptySortPlusPlus(CLAUSE GivenClause, st_INDEX Index,
+				  SORTTHEORY SortTheory, FLAGSTORE Flags,
+				  PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause,  an 'Index' of clauses, a sort theory, a flag store
+           and a precedence.
+           The sort constraint of the clause must not contain a
+	   non-variable term, but the sort constraint has to be unsolved.
+  RETURNS: A list of clauses derived from the GivenClause by
+           the Empty Sort rule.
+  MEMORY:  Memory is allocated for the returned list and the clauses.
+***************************************************************/
+{
+  LIST     result;
+  int      i, lc;
+  BOOL     hit;
+  
+#ifdef CHECK
+  if (clause_HasTermSortConstraintLits(GivenClause) ||
+      clause_HasSolvedConstraint(GivenClause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_ForwardEmptySortPlusPlus: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  result = list_Nil();
+  lc     = clause_LastConstraintLitIndex(GivenClause);
+  hit    = FALSE;
+  
+  for (i = clause_FirstLitIndex(); i <= lc && !hit; i++) {
+
+    if (term_IsVariable(term_FirstArgument(clause_GetLiteralAtom(GivenClause,i)))) {
+      LITERAL tLit;
+      TERM    var;
+      int     j, ls;
+      BOOL varOccursNoMore;
+
+      tLit            = clause_GetLiteral(GivenClause, i);
+      var             = term_FirstArgument(clause_LiteralAtom(tLit));
+      ls              = clause_LastSuccedentLitIndex(GivenClause);
+      varOccursNoMore = TRUE;
+      /* Check if the variable occurs in antecedent or succedent literals */
+      for (j = clause_FirstAntecedentLitIndex(GivenClause); 
+	   (j <= ls) && varOccursNoMore; j++) {
+	if (term_ContainsSymbol(clause_GetLiteralAtom(GivenClause,j),
+				term_TopSymbol(var)))
+	  varOccursNoMore = FALSE;
+      }
+		
+      if (varOccursNoMore) {
+	/* Condition implies that constraint is unsolved */
+	LIST unifiers;
+
+	unifiers = inf_GetForwardPartnerLits(tLit, Index);
+	hit      = TRUE;  /* We found the first appropriate constraint literal */
+
+	if (!list_Empty(unifiers)) {
+	  TERM tAtom = clause_LiteralAtom(tLit);
+	  LIST tLits, sojuList;
+	  SORT tSort, unifierSort;
+
+	  /* Search the other T_k(t) in GivenClause */
+	  tLits = list_Nil();
+	  tSort = sort_TopSort();
+	  for (j = lc; j > i; j--) {
+	    TERM actAtom;
+
+	    actAtom = clause_GetLiteralAtom(GivenClause, j);
+	    if (term_FirstArgument(actAtom) == var) {   /* tClause is shared */
+	      tLits = list_Cons((POINTER)j, tLits);
+	      tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory,
+							     term_TopSymbol(actAtom)),
+				     tSort);
+	    }
+	  }
+	  tLits = list_Cons((POINTER)i, tLits);
+	  tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory,
+							 term_TopSymbol(tAtom)),
+				 tSort);
+	  list_PointerDeleteDuplicates(tSort);
+
+	  unifierSort = inf_GetSortFromLits(unifiers, SortTheory);
+	  sojuList    = sort_TheoryComputeAllSubsortHits(SortTheory, unifierSort, tSort);
+
+	  sort_Delete(unifierSort);
+	  sort_Delete(tSort);
+
+	  result =
+	    list_Nconc(inf_InternWeakening(GivenClause, tLits, unifiers, NULL,
+					   sojuList, Flags, Precedence),
+		       result);
+
+	  list_Delete(tLits);
+	  list_Delete(unifiers);
+	}
+      }
+    }
+  }
+  return result;
+}
+
+LIST inf_BackwardEmptySortPlusPlus(CLAUSE GivenClause, st_INDEX Index,
+				   SORTTHEORY SortTheory, FLAGSTORE Flags,
+				   PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause with solved sort constraint, an index of clauses,
+           a sort theory, a flag store and a precedence.
+  RETURNS: A list of clauses inferred from the GivenClause by
+           the Empty Sort rule.
+  MEMORY:  Memory is allocated for the list and the clauses.
+***************************************************************/
+{
+  LIST     result;
+  int      i, ls;
+
+#ifdef CHECK
+  if (!clause_HasSolvedConstraint(GivenClause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In inf_BackwardEmptySortPlusPlus: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  result = list_Nil();  
+  ls     = clause_LastSuccedentLitIndex(GivenClause);
+
+  for (i = clause_FirstSuccedentLitIndex(GivenClause); i <= ls; i++) {
+    LITERAL sLit;
+    TERM    sAtom;
+
+    sLit  = clause_GetLiteral(GivenClause, i);
+    sAtom = clause_LiteralAtom(sLit);
+    if (clause_LiteralGetFlag(sLit,STRICTMAXIMAL) && 
+	clause_LiteralIsSort(sLit) &&
+	(!term_IsVariable(term_FirstArgument(sAtom)) ||
+	 clause_HasEmptyConstraint(GivenClause))) {
+      LIST unifiers, partners;
+      SORT unifierSort;
+
+      unifiers = partners = list_Nil();
+      inf_GetBackwardPartnerLits(sLit, Index, &partners, &unifiers, TRUE, Flags,
+				 Precedence);
+      unifiers = list_Cons(sLit, unifiers);
+      /* <partners> holds monadic constraint literals */
+      /* <unifiers> holds monadic, maximal succedent literals */
+
+      unifierSort = inf_GetSortFromLits(unifiers, SortTheory);
+
+      for ( ; !list_Empty(partners); partners = list_Pop(partners)) {
+	LITERAL tLit;
+	CLAUSE  tClause;
+	TERM    tAtom;
+	int     ti;
+	int     li;
+	TERM    var;
+	BOOL    varOccursNoMore;
+	int     j;
+
+	tLit            = list_Car(partners);
+	tClause         = clause_LiteralOwningClause(tLit);
+	tAtom           = clause_LiteralAtom(tLit);
+	ti              = clause_LiteralGetIndex(tLit);
+	li              = clause_LastSuccedentLitIndex(tClause);
+	var             = term_FirstArgument(tAtom);
+	varOccursNoMore = TRUE;
+	for (j = clause_FirstAntecedentLitIndex(tClause);
+	     j <= li && varOccursNoMore;
+	     j++) {
+	  if (term_ContainsSymbol(clause_GetLiteralAtom(tClause,j),
+				  term_TopSymbol(var)))
+	    varOccursNoMore = FALSE;
+	}
+ 
+	if (varOccursNoMore) {
+	  /* Condition implies that constraint is unsolved */
+	  int  lc;
+	  LIST tLits, sojuList;
+	  SORT tSort;
+
+	  lc  = clause_LastConstraintLitIndex(tClause);
+
+	  /* Search the other T_k(t) in GivenClause */
+	  tLits = list_Nil();
+	  tSort = sort_TopSort();
+	  for (j = lc; j >= clause_FirstLitIndex(); j--) {
+	    TERM actAtom;
+	    
+	    actAtom = clause_GetLiteralAtom(tClause, j);
+	    if (j != ti &&
+		term_TopSymbol(term_FirstArgument(actAtom)) == term_TopSymbol(var)) {
+	      tLits = list_Cons((POINTER)j, tLits);
+	      tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(actAtom)),
+				     tSort);
+	    }
+	  }
+	  tLits = list_Cons((POINTER)ti, tLits);
+	  tSort = sort_Intersect(sort_TheorySortOfSymbol(SortTheory, term_TopSymbol(tAtom)),
+				 tSort);
+	  list_PointerDeleteDuplicates(tSort);
+
+	  sojuList = sort_TheoryComputeAllSubsortHits(SortTheory, unifierSort, tSort);
+	  sort_Delete(tSort);
+
+	  cont_StartBinding();
+	  unify_UnifyNoOC(cont_LeftContext(), tAtom,
+			  cont_RightContext(), sAtom);
+
+	  result =
+	    list_Nconc(inf_InternWeakening(tClause, tLits, unifiers, sLit,
+					   sojuList, Flags, Precedence),
+		       result);
+
+	  cont_BackTrack();
+
+	  list_Delete(tLits);
+	}
+      }
+      sort_Delete(unifierSort);
+      list_Delete(unifiers);
+    }
+  }
+
+  return result;
+}
diff --git a/test/spass/rules-sort.h b/test/spass/rules-sort.h
new file mode 100644
index 0000000000000000000000000000000000000000..6b83c94f1c4a91e7a67911e97f23879264957625
--- /dev/null
+++ b/test/spass/rules-sort.h
@@ -0,0 +1,79 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *           INFERENCE RULES FOR SORTS                    * */
+/* *                                                        * */
+/* *  $Module:   SORTRULES                                  * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1999, 2000, 2001            * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _SORTRULES_
+#define _SORTRULES_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "sort.h"
+#include "unify.h"
+#include "clause.h"
+#include "flags.h"
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/        
+
+LIST inf_ForwardSortResolution(CLAUSE, st_INDEX, SORTTHEORY, BOOL, FLAGSTORE,
+			       PRECEDENCE);
+LIST inf_BackwardSortResolution(CLAUSE, st_INDEX, SORTTHEORY, BOOL, FLAGSTORE,
+				PRECEDENCE);
+LIST inf_ForwardEmptySort(CLAUSE, st_INDEX, SORTTHEORY, BOOL, FLAGSTORE,
+			  PRECEDENCE);
+LIST inf_BackwardEmptySort(CLAUSE, st_INDEX, SORTTHEORY, BOOL, FLAGSTORE,
+			   PRECEDENCE);
+LIST inf_ForwardWeakening(CLAUSE, st_INDEX, SORTTHEORY, FLAGSTORE, PRECEDENCE);
+LIST inf_BackwardWeakening(CLAUSE, st_INDEX, SORTTHEORY, FLAGSTORE, PRECEDENCE);
+LIST inf_ForwardEmptySortPlusPlus(CLAUSE, st_INDEX, SORTTHEORY, FLAGSTORE,
+				  PRECEDENCE);
+LIST inf_BackwardEmptySortPlusPlus(CLAUSE, st_INDEX, SORTTHEORY, FLAGSTORE,
+				   PRECEDENCE);
+
+#endif
diff --git a/test/spass/rules-split.c b/test/spass/rules-split.c
new file mode 100644
index 0000000000000000000000000000000000000000..7ee420a9935febbbc3e13dd459aa48dc02bfc4cb
--- /dev/null
+++ b/test/spass/rules-split.c
@@ -0,0 +1,460 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *               SPLITTING OF CLAUSES                     * */
+/* *                                                        * */
+/* *  $Module:   SPLIT                                      * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 2000                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "rules-split.h"
+
+static LIST  split_DeleteClausesDependingOnLevelFromList(PROOFSEARCH,LIST, int, LIST*);
+static LIST  split_DeleteInvalidClausesFromList(PROOFSEARCH, int, LIST);
+static void  split_DeleteInvalidClausesFromStack(PROOFSEARCH);
+static LIST  split_RemoveUnnecessarySplits(PROOFSEARCH, CLAUSE);
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+
+LIST split_Backtrack(PROOFSEARCH PS, CLAUSE EmptyClause, CLAUSE* SplitClause) 
+/**************************************************************
+  INPUT:   A proofsearch object, an empty clause and a pointer to a clause
+           used as return value.
+  RETURNS: A list of clauses deleted in the backtracked split levels.
+           <*SplitClause> is set to the split clause for the right branch
+	   of the splitting step, or NULL, if the tableau is finished.
+  EFFECT:  Backtracks the top of the split stack wrt the empty clause's level
+***************************************************************/
+{
+  SPLIT ActBacktrackSplit;
+  LIST  RecoverList, Scan;
+  int   Backtracklevel;
+
+  ActBacktrackSplit = (SPLIT)NULL;
+  RecoverList       = split_RemoveUnnecessarySplits(PS, EmptyClause);
+  Backtracklevel    = clause_SplitLevel(EmptyClause);
+  *SplitClause      = NULL;
+
+  /* Backtrack all split levels bigger than the level of the empty clause */
+  while (!prfs_SplitStackEmpty(PS) && (prfs_ValidLevel(PS) > Backtracklevel)) {
+    ActBacktrackSplit = prfs_SplitStackTop(PS);
+    prfs_SplitStackPop(PS);
+    if (prfs_SplitFatherClause(ActBacktrackSplit) != (CLAUSE)NULL) {
+      RecoverList = list_Cons(prfs_SplitFatherClause(ActBacktrackSplit),
+			      RecoverList);
+      prfs_SplitSetFatherClause(ActBacktrackSplit, NULL);
+    }
+    RecoverList = list_Nconc(prfs_SplitDeletedClauses(ActBacktrackSplit),
+			     RecoverList);
+    clause_DeleteClauseList(prfs_SplitBlockedClauses(ActBacktrackSplit));
+    prfs_SplitFree(ActBacktrackSplit);
+    prfs_DecValidLevel(PS);
+  }
+  
+  /* Backtrack further for all right branches on top of the stack */
+  while (!prfs_SplitStackEmpty(PS) &&
+	 list_Empty(prfs_SplitBlockedClauses(prfs_SplitStackTop(PS)))) {
+    ActBacktrackSplit = prfs_SplitStackTop(PS);
+    prfs_SplitStackPop(PS);
+    if (prfs_SplitFatherClause(ActBacktrackSplit) != (CLAUSE)NULL)
+      RecoverList = list_Cons(prfs_SplitFatherClause(ActBacktrackSplit),
+			      RecoverList);
+    RecoverList = list_Nconc(prfs_SplitDeletedClauses(ActBacktrackSplit),
+			     RecoverList);
+    prfs_SplitFree(ActBacktrackSplit);
+    prfs_DecValidLevel(PS);
+  }
+  
+  if (!prfs_SplitStackEmpty(PS)) {
+    /* Enter the right branch of the splitting step */
+    int SplitMinus1;
+    LIST RightClauses;
+
+    SplitMinus1       = prfs_ValidLevel(PS) - 1;
+    ActBacktrackSplit = prfs_SplitStackTop(PS);
+
+    RecoverList       = list_Nconc(prfs_SplitDeletedClauses(ActBacktrackSplit),
+				   RecoverList);
+    prfs_SplitSetDeletedClauses(ActBacktrackSplit, list_Nil());    
+    RecoverList       = split_DeleteInvalidClausesFromList(PS, SplitMinus1,
+							   RecoverList);
+
+    RightClauses = prfs_SplitBlockedClauses(ActBacktrackSplit);
+    prfs_SplitSetBlockedClauses(ActBacktrackSplit, list_Nil());    
+    for (Scan = RightClauses; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+      if (clause_Number(list_Car(Scan)) == 0) {
+	/* Found the right clause, the negation clauses have number -1. */
+#ifdef CHECK
+	if (*SplitClause != NULL) {
+	  misc_StartErrorReport();
+	  misc_ErrorReport("\n In split_Backtrack:");
+	  misc_ErrorReport(" Found two blocked clauses ");
+	  misc_ErrorReport("\n with clause number 0 (this marks the clause ");
+	  misc_ErrorReport("\n for the right branch of the tableau).");
+	  misc_FinishErrorReport();
+	}
+#endif
+	*SplitClause = list_Car(Scan);
+      }
+      
+      clause_NewNumber((CLAUSE) list_Car(Scan));
+      clause_AddParentClause((CLAUSE) list_Car(Scan), clause_Number(EmptyClause));
+      clause_AddParentLiteral((CLAUSE) list_Car(Scan), 0);  /* dummy literal */
+    }
+
+#ifdef CHECK
+    if (*SplitClause == NULL) {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In split_Backtrack: Didn´t find a blocked clause");
+      misc_ErrorReport("\n with clause number 0. (this marks the clause ");
+      misc_ErrorReport("\n for the right branch of the tableau).");
+      misc_FinishErrorReport();
+    }
+#endif
+    
+    RecoverList = list_Nconc(RightClauses, RecoverList);
+
+    /* Then, delete clauses from current level (Hack) */
+    prfs_DecValidLevel(PS);
+    prfs_MoveInvalidClausesDocProof(PS);
+    split_DeleteInvalidClausesFromStack(PS);
+    prfs_IncValidLevel(PS);
+  } else {
+    /* Don't delete clauses from current level (split is top level) */
+    prfs_MoveInvalidClausesDocProof(PS);
+    for (Scan = RecoverList; !list_Empty(Scan); Scan = list_Cdr(Scan))
+      prfs_InsertDocProofClause(PS, list_Car(Scan));
+    list_Delete(RecoverList);
+    RecoverList = list_Nil();
+  }
+  prfs_SetLastBacktrackLevel(PS, prfs_ValidLevel(PS));
+
+  return RecoverList;
+}
+
+
+static LIST split_DeleteClausesDependingOnLevelFromList(PROOFSEARCH Search,
+							LIST ClauseList,
+							int Level, LIST* New)
+/**************************************************************
+  INPUT:   A proof search object, a list of unshared clauses
+           and a split level.
+  EFFECT:  Deletes all clauses depending on split level from
+           <ClauseList>.
+           All split stored deleted clauses from the level of
+           the deleted clauses from <ClauseList> are stored in
+           <*New>.
+  RETURNS: The updated list and the recover clauses in <*New>.
+***************************************************************/
+{
+  LIST   Scan;
+  CLAUSE Clause;
+  SPLIT  Reinsert;
+
+  for (Scan = ClauseList; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    Clause = list_Car(Scan);   
+    if (clause_DependsOnSplitLevel(Clause, Level)) {
+      Reinsert = prfs_GetSplitOfLevel(clause_SplitLevel(Clause), Search);
+      if (prfs_SplitDeletedClauses(Reinsert) != list_Nil()) {
+	*New = list_Nconc(prfs_SplitDeletedClauses(Reinsert), *New);
+	prfs_SplitSetDeletedClauses(Reinsert, list_Nil());
+      }
+      prfs_InsertDocProofClause(Search,Clause);
+      list_Rplaca(Scan, NULL);
+    }
+  }
+  return list_PointerDeleteElement(ClauseList, NULL);
+}
+ 
+
+static LIST split_DeleteClausesDependingOnLevelFromSet(PROOFSEARCH PS,
+						       LIST ClauseList,
+						       int SplitLevel)
+/**************************************************************
+  INPUT:   A PROOFSEARCH object, a list of shared clauses
+           and a split level.
+  RETURNS: A list of clauses that have to be recovered possibly.
+  EFFECT:  Clauses from the clause list depending on <SplitLevel>
+           are moved to the doc proof index of <PS>.
+           All formerly redundant clauses that were reduced by a clause
+           of the same split level as a clause from the list depending
+           on <SplitLevel> are returned.
+***************************************************************/
+{
+  LIST   scan, delList, recover;
+  CLAUSE clause;
+  SPLIT  reinsert;
+
+  delList = recover = list_Nil();
+
+  for (scan = ClauseList; !list_Empty(scan); scan = list_Cdr(scan)){
+    clause = list_Car(scan);
+    if (clause_DependsOnSplitLevel(clause, SplitLevel)) {
+      reinsert = prfs_GetSplitOfLevel(clause_SplitLevel(clause), PS);
+      recover = list_Nconc(prfs_SplitDeletedClauses(reinsert), recover);
+      prfs_SplitSetDeletedClauses(reinsert, list_Nil());
+      delList = list_Cons(clause, delList);
+    }
+  }
+
+  /* WARNING: The following move operations change the worked off */
+  /* and usable sets of the proof search object destructively.    */
+  /* So it's impossible to move those function calls into the     */
+  /* loop above.                                                  */
+  for ( ; !list_Empty(delList); delList = list_Pop(delList)) {
+    clause = list_Car(delList);
+    if (clause_GetFlag(clause, WORKEDOFF))
+      prfs_MoveWorkedOffDocProof(PS, clause);
+    else
+      prfs_MoveUsableDocProof(PS, clause);
+  }
+  return recover;
+}
+
+
+
+static LIST split_DeleteInvalidClausesFromList(PROOFSEARCH Search, int Level,
+					       LIST ClauseList)
+/**************************************************************
+  INPUT:   A proof search object, a split level and a list of clauses.
+  RETURNS: The list where invalid clauses wrt 'Level' are deleted.
+  EFFECT:  The invalid clauses are stored in the doc proof index
+           of the proof search object if necessary.
+***************************************************************/
+{
+  LIST   Scan;
+  CLAUSE Clause;
+
+  /*printf("\nDiese Liste soll von ungueltigen (Level > %d) "
+    "befreit werden: \n",Level);fflush(stdout);
+    clause_ListPrint(ClauseList);*/
+
+  for (Scan = ClauseList; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    Clause = list_Car(Scan);
+    if (!prfs_IsClauseValid(Clause,Level)) {
+      prfs_InsertDocProofClause(Search,Clause);
+      list_Rplaca(Scan, NULL);
+    }
+  }
+  return list_PointerDeleteElement(ClauseList, NULL);
+}
+
+static void split_DeleteInvalidClausesFromStack(PROOFSEARCH Search)
+/**************************************************************
+  INPUT:   A proof search object.            
+  EFFECT:  All clauses in the split stack of <Search> that have a higher
+           split level than the current <Search> split level are deleted.
+***************************************************************/
+{
+  LIST   Scan1,Scan2,ClauseList;
+  int    Level;
+  CLAUSE Clause;
+
+  Level = prfs_ValidLevel(Search);
+
+  for (Scan1=prfs_SplitStack(Search);!list_Empty(Scan1);Scan1=list_Cdr(Scan1)) {
+    ClauseList = prfs_SplitDeletedClauses(list_Car(Scan1));
+    for (Scan2 = ClauseList; !list_Empty(Scan2); Scan2 = list_Cdr(Scan2)) {
+      Clause = (CLAUSE)list_Car(Scan2);
+      if (!prfs_IsClauseValid(Clause,Level)) {
+	prfs_InsertDocProofClause(Search,Clause);
+	list_Rplaca(Scan2, NULL);
+      }
+    }
+    prfs_SplitSetDeletedClauses(list_Car(Scan1),list_PointerDeleteElement(ClauseList, NULL));
+  }
+}
+
+
+static LIST split_RemoveUnnecessarySplits(PROOFSEARCH PS, CLAUSE EmptyClause)
+/**************************************************************
+  INPUT:   An empty clause and a proof search object
+  EFFECT:  Removes all splits up to the last backtrack level
+           that were not necessary to derive the empty clause.
+  RETURNS: A list of recovered clauses.
+***************************************************************/
+{
+  LIST Scan;
+  LIST Recover, New;
+  LIST Deleted;
+  LIST ScanStack;
+
+  int SplitLevel;
+  int LastBacktrackLevel;
+  SPLIT Split,ScanSplit;
+
+  Scan               = prfs_SplitStack(PS);
+  SplitLevel         = prfs_ValidLevel(PS);
+  LastBacktrackLevel = prfs_LastBacktrackLevel(PS);
+  Recover            = list_Nil();
+
+  while (SplitLevel > LastBacktrackLevel) {
+    if (prfs_SplitIsUnused(list_Car(Scan)) &&
+	!clause_DependsOnSplitLevel(EmptyClause, SplitLevel)) {
+      New   = list_Nil();
+      Split = list_Car(Scan);
+
+      /*printf("\n\t Removed: %d",prfs_SplitSplitLevel(Split));*/
+      
+      clause_DeleteClauseList(prfs_SplitBlockedClauses(Split));
+      prfs_SplitSetBlockedClauses(Split, list_Nil());
+      
+      Recover = list_Nconc(prfs_SplitDeletedClauses(Split), Recover);
+      prfs_SplitSetDeletedClauses(Split, list_Nil());
+      
+      if (prfs_SplitFatherClause(Split) != (CLAUSE)NULL) {
+	Recover = list_Cons(prfs_SplitFatherClause(Split),Recover);
+	prfs_SplitSetFatherClause(Split,NULL);
+      }
+      Recover = split_DeleteClausesDependingOnLevelFromList(PS, Recover, SplitLevel, &New);
+      
+      ScanStack = prfs_SplitStack(PS);
+      while (!list_StackEmpty(ScanStack) &&  
+	     prfs_SplitSplitLevel((ScanSplit = (SPLIT)list_Car(ScanStack))) > LastBacktrackLevel) {
+	Deleted = prfs_SplitDeletedClauses(ScanSplit);
+	prfs_SplitSetDeletedClauses(ScanSplit, list_Nil()); /* IMPORTANT!, see next line */
+	Deleted = split_DeleteClausesDependingOnLevelFromList(PS, Deleted, SplitLevel, &New);
+	prfs_SplitSetDeletedClauses(ScanSplit, Deleted);
+	ScanStack = list_Cdr(ScanStack);
+      }
+      
+      while (!list_Empty(New)) {
+	Deleted = list_Nil();
+	Recover = list_Nconc(split_DeleteClausesDependingOnLevelFromList(PS, New, SplitLevel, &Deleted),
+			     Recover);
+	New     = Deleted;
+      }
+      Recover = list_Nconc(Recover, 
+		    split_DeleteClausesDependingOnLevelFromSet(PS, prfs_UsableClauses(PS), SplitLevel));
+      Recover = list_Nconc(Recover,
+			   split_DeleteClausesDependingOnLevelFromSet(PS, prfs_WorkedOffClauses(PS), SplitLevel));
+      
+      prfs_SplitSetUsed(Split);
+    }
+    
+    SplitLevel--;
+    Scan = list_Cdr(Scan);
+  }
+  return Recover;
+}
+
+
+void split_DeleteClauseAtLevel(PROOFSEARCH PS, CLAUSE Clause, int Level)
+/**************************************************************
+  INPUT:   A clause, a level and a proofsearch object
+  RETURNS: Nothing.
+  EFFECT:  <Clause> is deleted from the usable or worked off set
+           and made unshared.
+***************************************************************/
+{
+  if (clause_GetFlag(Clause,WORKEDOFF)) 
+    prfs_ExtractWorkedOff(PS, Clause);
+  else 
+    prfs_ExtractUsable(PS, Clause);
+
+  split_KeepClauseAtLevel(PS, Clause, Level);
+}
+
+
+void split_KeepClauseAtLevel(PROOFSEARCH PS, CLAUSE Clause, int Level)
+/**************************************************************
+  INPUT:   A clause and a level as int.
+  RETURNS: None.
+  MEMORY:  A copy of clause is made and kept within the split stack.
+***************************************************************/
+{
+  SPLIT  Split;
+
+  Split = prfs_GetSplitOfLevel(Level, PS);
+  prfs_SplitSetDeletedClauses(Split,list_Cons(Clause, prfs_SplitDeletedClauses(Split)));
+}
+
+
+LIST split_ExtractEmptyClauses(LIST Clauses, LIST* EmptyClauses)
+/**************************************************************
+  INPUT:   A list of clauses and a pointer to a list of empty clauses.
+  RETURNS: <Clauses> without all empty clauses where the empty clauses
+           are moved to <EmptyClauses>
+  MEMORY:  Destructive on <Clauses>.
+***************************************************************/
+{
+  LIST   Scan;
+  CLAUSE Clause;
+
+  for (Scan=Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Clause = (CLAUSE)list_Car(Scan);
+    if (clause_IsEmptyClause(Clause)) {
+      *EmptyClauses = list_Cons(Clause,*EmptyClauses);
+      list_Rplaca(Scan,NULL);
+    }
+  }
+  Clauses = list_PointerDeleteElement(Clauses,NULL);
+
+  return Clauses;
+}
+
+CLAUSE split_SmallestSplitLevelClause(LIST Clauses)
+/**************************************************************
+  INPUT:   A non-empty list of clauses.
+  RETURNS: The clause with the smallest split level.
+***************************************************************/
+{
+  CLAUSE Result;
+
+  Result  = (CLAUSE)list_Car(Clauses);
+  Clauses = list_Cdr(Clauses);
+  
+  while (!list_Empty(Clauses)) {
+    if (clause_SplitLevel(Result) > clause_SplitLevel(list_Car(Clauses)))
+      Result  = list_Car(Clauses);
+    Clauses = list_Cdr(Clauses);
+  }
+
+  return Result;
+}
diff --git a/test/spass/rules-split.h b/test/spass/rules-split.h
new file mode 100644
index 0000000000000000000000000000000000000000..3423fa3d1d48c60ab43cc2e7e07b4b225c98698d
--- /dev/null
+++ b/test/spass/rules-split.h
@@ -0,0 +1,70 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *               SPLITTING OF CLAUSES                     * */
+/* *                                                        * */
+/* *  $Module:   SPLIT                                      * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 2000                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _RULES_SPLIT_
+#define _RULES_SPLIT_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "clause.h"
+#include "search.h"
+
+
+/**************************************************************/
+/* Function Prototypes                                        */
+/**************************************************************/        
+
+LIST   split_Backtrack(PROOFSEARCH, CLAUSE, CLAUSE*);
+void   split_KeepClauseAtLevel(PROOFSEARCH, CLAUSE, int);
+void   split_DeleteClauseAtLevel(PROOFSEARCH, CLAUSE, int);
+LIST   split_ExtractEmptyClauses(LIST, LIST*);
+CLAUSE split_SmallestSplitLevelClause(LIST);
+
+
+#endif
diff --git a/test/spass/rules-ur.c b/test/spass/rules-ur.c
new file mode 100644
index 0000000000000000000000000000000000000000..bd076517827b3e425f1ae829a99a0df9fd470d61
--- /dev/null
+++ b/test/spass/rules-ur.c
@@ -0,0 +1,385 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                UR-RESOLUTION                           * */
+/* *                                                        * */
+/* *  $Module:   INFERENCE RULES                            * */
+/* *                                                        * */
+/* *  Copyright (C) 1999, 2000, 2001 MPI fuer Informatik    * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* $RCSfile$ */
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "rules-ur.h"
+#include "list.h"
+
+
+static LIST inf_GetURPartnerLits(TERM Atom, LITERAL Lit,
+				 BOOL Unit, SHARED_INDEX Index)
+/**************************************************************
+  INPUT:   An atom, a literal, a boolean flag and a SHARED_INDEX.
+  RETURNS: A list of literals with sign complementary to <Lit>
+           that are unifiable with <Atom>. If <Unit> is true,
+	   only literals from unit clauses are returned, if <Unit>
+	   is false, only literals from non-unit clauses are
+	   returned.
+  EFFECT:  <Atom> is a copy of <Lit>'s atom where some substitution
+           was applied and equality literals might have been swapped.
+	   <Lit> is just needed to check whether the unifiable
+	   literals are complementary.
+***************************************************************/
+{
+  LIST    Result, Unifiers, LitScan;
+  LITERAL PLit;
+  int     length;
+
+  Result   = list_Nil();
+  Unifiers = st_GetUnifier(cont_LeftContext(), sharing_Index(Index),
+			   cont_RightContext(), Atom);
+  for ( ; !list_Empty(Unifiers); Unifiers = list_Pop(Unifiers)) {
+    if (!term_IsVariable(list_Car(Unifiers))) {
+      for (LitScan = sharing_NAtomDataList(list_Car(Unifiers));
+	   !list_Empty(LitScan); LitScan = list_Cdr(LitScan)) {
+	PLit   = list_Car(LitScan);
+	length = clause_Length(clause_LiteralOwningClause(PLit));
+	if (clause_LiteralsAreComplementary(Lit, PLit) &&
+	    ((Unit && length==1) || (!Unit && length!=1)))
+	  /* The partner literals must have complementary sign and
+	     if <Unit> == TRUE they must be from unit clauses,
+	     if <Unit> == FALSE they must be from non-unit clauses. */
+	  Result = list_Cons(PLit, Result);
+      }
+    }
+  }
+  return Result;
+}
+
+
+static CLAUSE inf_CreateURUnitResolvent(CLAUSE Clause, int i, SUBST Subst,
+					LIST FoundMap, FLAGSTORE Flags,
+					PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A non-unit clause, a literal index from the clause,
+           a substitution, a list of pairs (l1, l2) of literals,
+	   where l1 is from the non-unit clause and l2 is from a
+	   unit clause, a flag store and a precedence.
+  RETURNS: The resolvent of this UR resolution inference. The
+           clause consists of the literal at index <i> in <Clause>
+	   after application of <Subst>.
+  EFFECT:  The flag store and the precedence are needed to create
+           the new clause.
+***************************************************************/
+{
+  CLAUSE  Result, PClause;
+  LITERAL Lit;
+  TERM    Atom;
+  LIST    Parents;
+  NAT     depth;
+
+  /* Create atom for resolvent */
+  Atom = subst_Apply(Subst, term_Copy(clause_GetLiteralAtom(Clause, i)));
+  /* Create clause */
+  Parents = list_List(Atom);
+  if (i <= clause_LastConstraintLitIndex(Clause))
+    Result = clause_Create(Parents, list_Nil(), list_Nil(), Flags, Precedence);
+  else if (i <= clause_LastAntecedentLitIndex(Clause))
+    Result = clause_Create(list_Nil(), Parents, list_Nil(), Flags, Precedence);
+  else
+    Result = clause_Create(list_Nil(), list_Nil(), Parents, Flags, Precedence);
+  list_Delete(Parents);
+
+  /* Get parent clauses and literals, calculate depth of resolvent */
+  Parents = list_List(Clause);
+  depth   = clause_Depth(Clause);
+  for ( ; !list_Empty(FoundMap); FoundMap = list_Cdr(FoundMap)) {
+    Lit     = list_PairSecond(list_Car(FoundMap)); /* Literal from unit */ 
+    PClause = clause_LiteralOwningClause(Lit);
+    Parents = list_Cons(PClause, Parents);
+    depth   = misc_Max(depth, clause_Depth(PClause));
+    clause_AddParentClause(Result, clause_Number(PClause));
+    clause_AddParentLiteral(Result, clause_LiteralGetIndex(Lit));
+
+    Lit     = list_PairFirst(list_Car(FoundMap)); /* Is from <Clause> */
+    clause_AddParentClause(Result, clause_Number(Clause));
+    clause_AddParentLiteral(Result, clause_LiteralGetIndex(Lit));
+  }
+  clause_SetFromURResolution(Result);
+  clause_SetDepth(Result, depth+1);
+  clause_SetSplitDataFromList(Result, Parents);
+  list_Delete(Parents);
+
+  return Result;
+}
+
+
+static LIST inf_SearchURResolvents(CLAUSE Clause, int i, LIST FoundMap,
+				   LIST RestLits, SUBST Subst,
+				   SYMBOL GlobalMaxVar, SHARED_INDEX Index,
+				   FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A non-unit clause, a literal index from <Clause>.
+           <FoundMap> is a list of pairs (l1,l2) of unifiable literals,
+	   where l1 is from <Clause> and l2 is from a unit clause.
+	   <RestLits> is a list of literals from <Clause> where
+	   we haven't found unifiable literals from unit clauses
+	   so far.
+	   <Subst> is the overall substitution for <Clause>
+	   (not for the unit-clauses!).
+	   <GlobalMaxVar> is the maximal variable encountered so far.
+	   <Index> is used to search unifiable literals.
+	   The flag store and the precedence are needed to create
+	   the new clauses.
+  RETURNS: A list of UR resolution resolvents.
+***************************************************************/
+{
+  if (list_Empty(RestLits)) {
+    /* Stop the recursion */
+    return list_List(inf_CreateURUnitResolvent(Clause, i, Subst, FoundMap,
+					       Flags, Precedence));
+  } else {
+    LITERAL Lit, PLit;
+    SYMBOL  NewMaxVar;
+    SUBST   NewSubst, RightSubst;
+    TERM    AtomCopy, PAtom;
+    LIST    Result, Partners;
+    BOOL    Swapped;
+
+    Result   = list_Nil();
+    Swapped  = FALSE;
+    /* Choose the unmatched literal with the most symbols */
+    RestLits = clause_MoveBestLiteralToFront(list_Copy(RestLits), Subst,
+					     GlobalMaxVar,
+					     clause_HyperLiteralIsBetter);
+    Lit      = list_Car(RestLits);
+    RestLits = list_Pop(RestLits);
+    AtomCopy = subst_Apply(Subst, term_Copy(clause_LiteralAtom(Lit)));
+
+    /* The following 'endless' loop runs twice for equality literals */
+    /* and only once for other literals.                             */
+    while (TRUE) {
+      Partners = inf_GetURPartnerLits(AtomCopy, Lit, TRUE, Index);
+      for ( ; !list_Empty(Partners); Partners = list_Pop(Partners)) {
+	PLit    = list_Car(Partners);
+
+	/* Rename the atom */
+	PAtom   = term_Copy(clause_LiteralAtom(PLit));
+	term_StartMaxRenaming(GlobalMaxVar);
+	term_Rename(PAtom);
+	/* Get the new global maximal variable */
+	NewMaxVar = term_MaxVar(PAtom);
+	if (symbol_GreaterVariable(GlobalMaxVar, NewMaxVar))
+	  NewMaxVar = GlobalMaxVar;
+	
+	/* Get the substitution */
+	cont_Check();
+	if (!unify_UnifyNoOC(cont_LeftContext(), AtomCopy,
+			     cont_RightContext(), PAtom)) {
+	  misc_StartErrorReport();
+	  misc_ErrorReport("\n In inf_SearchURResolvents: Unification failed.");
+	  misc_FinishErrorReport();
+	}
+	subst_ExtractUnifier(cont_LeftContext(), &NewSubst,
+			     cont_RightContext(), &RightSubst);
+	cont_Reset();
+	subst_Delete(RightSubst);  /* Forget substitution for unit clause */
+	term_Delete(PAtom);  /* Was just needed to get the substitution */
+
+	/* Build the composition of the substitutions */
+	RightSubst = NewSubst;
+	NewSubst = subst_Compose(NewSubst, subst_Copy(Subst));
+	subst_Delete(RightSubst);
+
+	FoundMap    = list_Cons(list_PairCreate(Lit, PLit), FoundMap);
+	
+	Result = list_Nconc(inf_SearchURResolvents(Clause,i,FoundMap,RestLits,
+						   NewSubst,NewMaxVar,Index,
+						   Flags, Precedence),
+			    Result);
+	
+	list_PairFree(list_Car(FoundMap));
+	FoundMap = list_Pop(FoundMap);
+	subst_Delete(NewSubst);
+      }
+      /* loop control */
+      if (!fol_IsEquality(AtomCopy) || Swapped)
+	break;
+      else {
+	term_EqualitySwap(AtomCopy);
+	Swapped = TRUE;
+      }
+    }
+    /* cleanup */
+    term_Delete(AtomCopy);
+    list_Delete(RestLits);
+    
+    return Result;
+  }
+}
+
+
+static LIST inf_NonUnitURResolution(CLAUSE Clause, int SpecialLitIndex,
+				    LIST FoundMap, SUBST Subst,
+				    SYMBOL GlobalMaxVar, SHARED_INDEX Index,
+				    FLAGSTORE Flags, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A non-unit clause, a literal index from <Clause>.
+           <FoundMap> is a list of pairs (l1,l2) of unifiable literals,
+	   where l1 is from <Clause> and l2 is from a unit clause.
+	   At this point the list has at most one element.
+	   <Subst> is the substitution for <Clause>.
+	   <GlobalMaxVar> is the maximal variable encountered so far.
+	   <Index> is used to search unifiable literals.
+	   The flag store and the precedence are needed to create
+	   the new clauses.
+  RETURNS: The list of UR resolution resolvents.
+  EFFECT:  If inf_URResolution was called with a unit clause,
+           <SpecialLitIndex> is the index of a literal from a non-unit
+	   clause, that is unifiable with the unit clause's literal,
+	   otherwise it is set to -1.
+***************************************************************/
+{
+  LIST Result, RestLits;
+  int  i, last;
+
+  Result = list_Nil();
+  RestLits = clause_GetLiteralListExcept(Clause, SpecialLitIndex);
+  last = clause_LastLitIndex(Clause);
+  for (i = clause_FirstLitIndex(); i <= last; i++) {
+    /* <i> is the index of the literal that remains in the resolvent */
+    if (i != SpecialLitIndex) {
+      RestLits = list_PointerDeleteOneElement(RestLits,
+					      clause_GetLiteral(Clause,i));
+      
+      Result = list_Nconc(inf_SearchURResolvents(Clause, i, FoundMap, RestLits,
+						 Subst, GlobalMaxVar, Index,
+						 Flags, Precedence),
+			  Result);
+      
+      RestLits = list_Cons(clause_GetLiteral(Clause, i), RestLits);
+    }
+  }
+  list_Delete(RestLits);
+  return Result;
+}
+
+
+LIST inf_URResolution(CLAUSE Clause, SHARED_INDEX Index, FLAGSTORE Flags,
+		      PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, a shared index, a flag store and a precedence.
+  RETURNS: The list of UR resolution resolvents.
+  EFFECT:  The flag store and the precedence are needed to create
+           the resolvents.
+***************************************************************/
+{
+  LIST Result;
+
+  if (clause_Length(Clause) != 1) {
+    /* Clause isn't unit clause */
+    Result = inf_NonUnitURResolution(Clause, -1, list_Nil(), subst_Nil(),
+				     clause_MaxVar(Clause), Index, Flags,
+				     Precedence);
+  }
+  else {
+    /* Clause is unit clause, so search partner literals in non-unit clauses */
+    LITERAL Lit, PLit;
+    TERM    Atom;
+    LIST    Partners, FoundMap;
+    SYMBOL  MaxVar, PMaxVar;
+    SUBST   LeftSubst, RightSubst;
+    CLAUSE  PClause;
+    int     PLitInd;
+    BOOL    Swapped;
+
+    Result   = list_Nil();
+    Lit      = clause_GetLiteral(Clause, clause_FirstLitIndex());
+    Atom     = term_Copy(clause_LiteralAtom(Lit));
+    Swapped  = FALSE;
+
+    /* The following 'endless' loop runs twice for equality literals */
+    /* and only once for other literals.                             */
+    while (TRUE) {
+      /* Get complementary literals from non-unit clauses */
+      Partners = inf_GetURPartnerLits(Atom, Lit, FALSE, Index);
+      
+      for ( ; !list_Empty(Partners); Partners = list_Pop(Partners)) {
+	PLit     = list_Car(Partners);
+	PLitInd  = clause_LiteralGetIndex(PLit);
+	PClause  = clause_LiteralOwningClause(PLit); /* non-unit clause */
+	
+	PMaxVar   = clause_MaxVar(PClause);
+	term_StartMaxRenaming(PMaxVar);
+	term_Rename(Atom);              /* Rename atom from unit clause */
+	MaxVar = term_MaxVar(Atom); 
+	if (symbol_GreaterVariable(PMaxVar, MaxVar))
+	  MaxVar = PMaxVar;
+	
+	/* Get the substitution */
+	cont_Check();
+	unify_UnifyNoOC(cont_LeftContext(), clause_LiteralAtom(PLit),
+			cont_RightContext(), Atom);
+	subst_ExtractUnifier(cont_LeftContext(), &LeftSubst,
+			     cont_RightContext(), &RightSubst);
+	cont_Reset();
+	/* We don't need the substitution for the unit clause */
+	subst_Delete(RightSubst);
+	
+	FoundMap = list_List(list_PairCreate(PLit, Lit));
+	
+	Result = list_Nconc(inf_NonUnitURResolution(PClause, PLitInd, FoundMap,
+						    LeftSubst, MaxVar, Index,
+						    Flags, Precedence),
+			    Result);
+	
+	list_DeletePairList(FoundMap);
+	subst_Delete(LeftSubst);
+      }
+      /* loop control */
+      if (!fol_IsEquality(Atom) || Swapped)
+	break;
+      else {
+	term_EqualitySwap(Atom);
+	Swapped = TRUE;
+      }
+    }  /* end of endless loop */
+    term_Delete(Atom);
+  }
+  return Result;
+}
diff --git a/test/spass/rules-ur.h b/test/spass/rules-ur.h
new file mode 100644
index 0000000000000000000000000000000000000000..3bdc4272f07d36ec56365784b5944551f38945b6
--- /dev/null
+++ b/test/spass/rules-ur.h
@@ -0,0 +1,55 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                UR-RESOLUTION                           * */
+/* *                                                        * */
+/* *  $Module:   INFERENCE RULES                            * */
+/* *                                                        * */
+/* *  Copyright (C) 1999, 2000, 2001 MPI fuer Informatik    * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* $RCSfile$ */
+
+#ifndef _UR_RESOLUTION_
+#define _UR_RESOLUTION_
+
+#include "clause.h"
+#include "sharing.h"
+#include "flags.h"
+
+LIST inf_URResolution(CLAUSE, SHARED_INDEX, FLAGSTORE, PRECEDENCE);
+
+#endif
diff --git a/test/spass/search.c b/test/spass/search.c
new file mode 100644
index 0000000000000000000000000000000000000000..5833ada5abd1d22843e5c28eb07a9bc34e6aa178
--- /dev/null
+++ b/test/spass/search.c
@@ -0,0 +1,1271 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *          REPRESENTATION OF PROOF SEARCH                * */
+/* *                                                        * */
+/* *  $Module:   PROOF SEARCH                               * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1997, 1998, 1999, 2000, 2001            * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#include "search.h"
+#include "defs.h"
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+static SPLIT prfs_SplitCreate(PROOFSEARCH PS)
+/**************************************************************
+  INPUT:   A proofsearch object
+  RETURNS: A new split object, which is initialized.
+  MEMORY:  Allocates memory for the SPLIT_NODE.
+  EFFECT:  Increases the split level of the proof search object.
+***************************************************************/
+{
+  SPLIT Result;
+
+  prfs_IncValidLevel(PS);
+
+  Result                 = (SPLIT)memory_Malloc(sizeof(SPLIT_NODE));
+  Result->splitlevel     = prfs_ValidLevel(PS);
+  Result->used           = FALSE;
+  Result->blockedClauses = list_Nil();
+  Result->deletedClauses = list_Nil();
+  Result->father         = (CLAUSE) NULL;
+  return Result;
+}
+
+
+static void prfs_SplitDelete(SPLIT S)
+/**************************************************************
+  INPUT:   A split 
+  RETURNS: Nothing.
+  MEMORY:  Deletes blocked and deleted clauses. Frees the split.
+***************************************************************/
+{
+  clause_DeleteClauseList(S->blockedClauses);
+  clause_DeleteClauseList(S->deletedClauses);
+  if (S->father != (CLAUSE)NULL)
+    clause_Delete(S->father);
+  prfs_SplitFree(S);
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *		    DEBUGGING FUNCTIONS	         	    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+BOOL prfs_Check(PROOFSEARCH Search)
+/**************************************************************
+  INPUT:   A proof search object.
+  EFFECT:  None.
+  RETURNS: TRUE if all invariants about <Search> are valid.
+***************************************************************/
+{
+  LIST   Scan,Clauses;
+  SPLIT  Split;
+  CLAUSE Clause;
+
+  for (Scan=prfs_UsableClauses(Search);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Clause = (CLAUSE)list_Car(Scan);
+    if (!clause_IsClause(Clause, prfs_Store(Search), prfs_Precedence(Search)) ||
+	clause_GetFlag(Clause, WORKEDOFF) ||
+	!prfs_IsClauseValid(Clause, prfs_ValidLevel(Search)))
+      return FALSE;
+  }
+
+  for (Scan=prfs_WorkedOffClauses(Search);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Clause = (CLAUSE)list_Car(Scan);
+    if (!clause_IsClause(Clause, prfs_Store(Search), prfs_Precedence(Search)) ||
+	!clause_GetFlag(Clause,WORKEDOFF) ||
+	!prfs_IsClauseValid(Clause, prfs_ValidLevel(Search)))
+      return FALSE;
+  }
+
+  for (Scan=prfs_SplitStack(Search); !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+    Split = (SPLIT)list_Car(Scan);
+    if (prfs_SplitIsUsed(Split)) {
+      if (!list_Empty(prfs_SplitBlockedClauses(Split)) ||
+	  !list_Empty(prfs_SplitDeletedClauses(Split))) {
+	/*putchar('\n');prfs_PrintSplit(Split); putchar('\n');*/
+	return FALSE;
+      } else {
+	for (Clauses=prfs_UsableClauses(Search);!list_Empty(Clauses);Clauses=list_Cdr(Clauses))
+	  if (clause_SplitLevel(list_Car(Clauses)) == prfs_SplitSplitLevel(Split)) {
+	    /*puts("\n");prfs_PrintSplit(Split); 
+	      fputs("\n Clause must not exist: ",stdout);
+	      clause_Print(list_Car(Clauses)); putchar('\n');*/
+	    return FALSE;
+	  }
+	for (Clauses=prfs_WorkedOffClauses(Search);!list_Empty(Clauses);Clauses=list_Cdr(Clauses))
+	  if (clause_SplitLevel(list_Car(Clauses)) == prfs_SplitSplitLevel(Split)) {
+	    /*puts("\n");prfs_PrintSplit(Split);
+	      fputs("\n Clause must not exist: ",stdout);
+	      clause_Print(list_Car(Clauses)); putchar('\n');*/
+	    return FALSE;
+	  }
+      }
+    } 
+  }
+  
+  if (prfs_ValidLevel(Search) == 0) {
+    if (!prfs_SplitStackEmpty(Search))
+      return FALSE;
+  } else {
+    if (prfs_ValidLevel(Search) != prfs_SplitSplitLevel(prfs_SplitStackTop(Search)))
+      return FALSE;
+  }
+
+  if (prfs_ValidLevel(Search) < prfs_LastBacktrackLevel(Search))
+    return FALSE;
+
+  return TRUE;
+}
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *			HIGH LEVEL FUNCTIONS		    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+static void prfs_InsertInSortTheories(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A proof search object and a clause.
+  EFFECT:  If the clause is a declaration clause it is inserted
+           into the dynamic and approximated dynamic sort theory.
+  RETURNS: Nothing.
+***************************************************************/
+{
+  if ((prfs_DynamicSortTheory(Search) != (SORTTHEORY)NULL ||
+       prfs_ApproximatedDynamicSortTheory(Search) != (SORTTHEORY)NULL) &&
+      clause_IsDeclarationClause(Clause)) {
+    int     i,l;
+    LITERAL lit;
+    CLAUSE  copy;
+    LIST    approx;
+    l = clause_Length(Clause);
+    for (i = clause_FirstSuccedentLitIndex(Clause); i < l; i++) {
+      lit = clause_GetLiteral(Clause,i);
+      if (clause_LiteralIsMaximal(lit) && 
+	  symbol_IsBaseSort(term_TopSymbol(clause_LiteralSignedAtom(lit)))) {
+	if (prfs_DynamicSortTheory(Search) != (SORTTHEORY)NULL) {
+	  copy = clause_Copy(Clause);
+	  list_Delete(clause_ParentClauses(copy));
+	  clause_SetParentClauses(copy,list_Nil());
+	  list_Delete(clause_ParentLiterals(copy));
+	  clause_SetParentLiterals(copy,list_Nil());
+	  clause_SetNumber(copy,clause_Number(Clause));
+	  sort_TheoryInsertClause(prfs_DynamicSortTheory(Search),Clause,
+				  copy,clause_GetLiteral(copy,i));
+	}
+	if (prfs_ApproximatedDynamicSortTheory(Search) != (SORTTHEORY)NULL) {
+	  approx = sort_ApproxMaxDeclClauses(Clause, prfs_Store(Search),
+					     prfs_Precedence(Search));
+	  for ( ; !list_Empty(approx); approx = list_Pop(approx)) {
+	    copy = (CLAUSE)list_Car(approx);
+	    sort_TheoryInsertClause(prfs_ApproximatedDynamicSortTheory(Search),
+				    Clause, copy, 
+				    clause_GetLiteral(copy,clause_FirstSuccedentLitIndex(copy)));
+	  }
+	}
+      }
+    }
+  }
+}
+
+
+static void prfs_DeleteFromSortTheories(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A proof search object and a clause.
+  RETURNS: Nothing.
+  EFFECT:  If the clause is a declaration clause it is deleted
+           from the dynamic and approximated dynamic sort theory.
+***************************************************************/
+{
+  if (clause_IsDeclarationClause(Clause)) {
+    if (prfs_DynamicSortTheory(Search) != (SORTTHEORY)NULL)
+      sort_TheoryDeleteClause(prfs_DynamicSortTheory(Search), Clause);
+    if (prfs_ApproximatedDynamicSortTheory(Search) != (SORTTHEORY)NULL)
+      sort_TheoryDeleteClause(prfs_ApproximatedDynamicSortTheory(Search), Clause);
+  }
+}
+
+
+void prfs_DeleteDocProof(PROOFSEARCH Search)
+/**************************************************************
+  INPUT:   A proof search object.
+  RETURNS: Nothing.
+  EFFECT:  The docproof structures are deleted.
+***************************************************************/
+{
+  clause_DeleteSharedClauseList(prfs_DocProofClauses(Search),
+				prfs_DocProofSharingIndex(Search),
+				prfs_Store(Search), prfs_Precedence(Search));
+  if (prfs_DocProofSharingIndex(Search))
+    sharing_IndexDelete(prfs_DocProofSharingIndex(Search));
+  Search->dpindex = NULL;
+  Search->dplist  = list_Nil();
+}
+
+
+static void prfs_InternalDelete(PROOFSEARCH Search)
+/**************************************************************
+  INPUT:   A proof search object.
+  RETURNS: Nothing.
+  EFFECT:  Most of the proofsearch object is deleted.
+           This function implements the common subset of
+	   functionality of prfs_Clean and prfs_Delete.
+***************************************************************/
+{
+  LIST Scan;
+
+  clause_DeleteClauseList(prfs_EmptyClauses(Search));
+  list_DeleteWithElement(prfs_Definitions(Search),
+			 (void (*)(POINTER)) def_Delete);
+  list_Delete(prfs_UsedEmptyClauses(Search));
+  sort_TheoryDelete(prfs_StaticSortTheory(Search));
+  sort_TheoryDelete(prfs_DynamicSortTheory(Search));
+  sort_TheoryDelete(prfs_ApproximatedDynamicSortTheory(Search));
+  clause_DeleteSharedClauseList(prfs_WorkedOffClauses(Search),
+				prfs_WorkedOffSharingIndex(Search),
+				prfs_Store(Search), prfs_Precedence(Search));
+  clause_DeleteSharedClauseList(prfs_UsableClauses(Search),
+				prfs_UsableSharingIndex(Search),
+				prfs_Store(Search), prfs_Precedence(Search));
+  clause_DeleteSharedClauseList(prfs_DocProofClauses(Search),
+				prfs_DocProofSharingIndex(Search),
+				prfs_Store(Search), prfs_Precedence(Search));
+  prfs_DeleteFinMonPreds(Search);
+  for (Scan=prfs_SplitStack(Search); !list_Empty(Scan); Scan=list_Cdr(Scan))
+    prfs_SplitDelete(list_Car(Scan));
+  list_Delete(prfs_SplitStack(Search));
+}
+
+
+void prfs_Delete(PROOFSEARCH Search)
+/**************************************************************
+  INPUT:   A proof search object.
+  RETURNS: Nothing.
+  EFFECT:  The whole structure including all its substructures 
+           is deleted.
+***************************************************************/
+{
+  prfs_InternalDelete(Search);
+
+  sharing_IndexDelete(prfs_WorkedOffSharingIndex(Search));
+  sharing_IndexDelete(prfs_UsableSharingIndex(Search));
+  if (prfs_DocProofSharingIndex(Search))
+    sharing_IndexDelete(prfs_DocProofSharingIndex(Search));
+  flag_DeleteStore(prfs_Store(Search));
+  symbol_DeletePrecedence(prfs_Precedence(Search));
+  memory_Free(Search,sizeof(PROOFSEARCH_NODE));
+}
+
+
+void prfs_Clean(PROOFSEARCH Search)
+/**************************************************************
+  INPUT:   A proof search object.
+  RETURNS: Nothing.
+  EFFECT:  All clauses are deleted. The structure is cleaned
+           and initialized.
+***************************************************************/
+{
+  prfs_InternalDelete(Search);
+
+  Search->emptyclauses     = list_Nil();
+  Search->definitions      = list_Nil();
+  Search->usedemptyclauses = list_Nil();
+  Search->wolist           = list_Nil();
+  Search->uslist           = list_Nil();
+  Search->finmonpreds      = list_Nil();
+  Search->astatic          = (SORTTHEORY)NULL;
+  Search->adynamic         = (SORTTHEORY)NULL;
+  Search->dynamic          = (SORTTHEORY)NULL;
+  Search->dplist           = list_Nil();
+  
+  Search->stack               = list_StackBottom();
+  Search->validlevel          = 0;
+  Search->lastbacktrack       = 0;
+  Search->splitcounter        = 0;
+  Search->keptclauses         = 0;
+  Search->derivedclauses      = 0;
+  Search->loops               = 0;
+  Search->backtracked         = 0;
+  Search->nontrivclausenumber = 0;
+
+  symbol_ClearPrecedence(prfs_Precedence(Search));
+}
+
+
+void prfs_SwapIndexes(PROOFSEARCH Search)
+/**************************************************************
+  INPUT:   A proof search object.
+  RETURNS: Nothing.
+  EFFECT:  The usable and worked-off indexes are exchanged.
+***************************************************************/
+{
+  LIST         Scan;
+  SHARED_INDEX Help;
+
+  Help = prfs_WorkedOffSharingIndex(Search);
+  Scan = prfs_WorkedOffClauses(Search);
+  prfs_SetWorkedOffClauses(Search,prfs_UsableClauses(Search));
+  Search->woindex = prfs_UsableSharingIndex(Search);
+  prfs_SetUsableClauses(Search, Scan);
+  Search->usindex = Help;
+
+  for (Scan=prfs_UsableClauses(Search); !list_Empty(Scan); Scan=list_Cdr(Scan))
+    clause_RemoveFlag(list_Car(Scan), WORKEDOFF);
+  for (Scan=prfs_WorkedOffClauses(Search);!list_Empty(Scan);Scan=list_Cdr(Scan))
+    clause_SetFlag(list_Car(Scan), WORKEDOFF);
+}
+
+
+PROOFSEARCH prfs_Create(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: A new proof search object. The worked off and usable
+           indexes are created whilst the docproof index and the
+	   sort theories are not created, since they are not
+	   needed in general.
+***************************************************************/
+{
+  PROOFSEARCH Result;
+
+  Result = memory_Malloc(sizeof(PROOFSEARCH_NODE));
+
+  Result->emptyclauses = list_Nil();
+  Result->definitions  = list_Nil();
+  Result->usedemptyclauses = list_Nil();
+  Result->woindex      = sharing_IndexCreate();
+  Result->wolist       = list_Nil();
+  Result->usindex      = sharing_IndexCreate();
+  Result->uslist       = list_Nil();
+  Result->finmonpreds  = list_Nil();
+
+  Result->astatic      = (SORTTHEORY)NULL;
+  Result->adynamic     = (SORTTHEORY)NULL;
+  Result->dynamic      = (SORTTHEORY)NULL;
+
+  Result->precedence   = symbol_CreatePrecedence();
+
+  Result->store        = flag_CreateStore();
+  flag_InitStoreByDefaults(Result->store);
+  
+  Result->dpindex      = (SHARED_INDEX)NULL;
+  Result->dplist       = list_Nil();
+  
+  Result->stack               = list_StackBottom();
+  Result->validlevel          = 0;
+  Result->lastbacktrack       = 0;
+  Result->splitcounter        = 0;
+  Result->keptclauses         = 0;
+  Result->derivedclauses      = 0;
+  Result->loops               = 0;
+  Result->backtracked         = 0;
+  Result->nontrivclausenumber = 0;
+    
+  return Result;  
+}
+
+
+void prfs_CopyIndices(PROOFSEARCH Search, PROOFSEARCH SearchCopy) 
+/**************************************************************
+  INPUT:   A proof search object and a clean proof search object.
+  RETURNS: Nothing.
+  EFFECT:  Copies the indices from Search to SearchCopy.
+  CAUTION: Splitstack and theories are not copied!
+***************************************************************/
+{
+  LIST Scan;
+
+  /* If a DocProof index is required but not yet allocated in SearchCopy,
+     do it now */
+  if (prfs_DocProofSharingIndex(Search) != NULL &&
+      prfs_DocProofSharingIndex(SearchCopy) == NULL)
+    prfs_AddDocProofSharingIndex(SearchCopy);
+
+  /* Copy usable, worked-off and docproof index */
+  for (Scan = prfs_UsableClauses(Search); !list_Empty(Scan); Scan = list_Cdr(Scan))
+    prfs_InsertUsableClause(SearchCopy, clause_Copy((CLAUSE) list_Car(Scan)));
+
+  for (Scan = prfs_WorkedOffClauses(Search); !list_Empty(Scan); Scan = list_Cdr(Scan))
+    prfs_InsertWorkedOffClause(SearchCopy, clause_Copy((CLAUSE) list_Car(Scan)));
+
+  for (Scan = prfs_DocProofClauses(Search); !list_Empty(Scan); Scan = list_Cdr(Scan))
+    prfs_InsertDocProofClause(SearchCopy, clause_Copy((CLAUSE) list_Car(Scan)));
+}
+
+
+void prfs_InsertWorkedOffClause(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A proof search object and a clause.
+  RETURNS: Nothing.
+  MEMORY:  The clause is assumed to be unshared.
+  EFFECT:  The clause is inserted into the worked off sharing index
+           and list of <Search>. The unshared literals are deleted.
+***************************************************************/
+{
+#ifdef CHECK
+  if (!clause_IsClause(Clause,prfs_Store(Search), prfs_Precedence(Search))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In prfs_InsertWorkedOffClause: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif 
+
+  clause_SetFlag(Clause,WORKEDOFF);
+  prfs_SetWorkedOffClauses(Search,list_Cons(Clause, prfs_WorkedOffClauses(Search)));
+  clause_InsertIntoSharing(Clause, prfs_WorkedOffSharingIndex(Search),
+			   prfs_Store(Search), prfs_Precedence(Search));
+  prfs_InsertInSortTheories(Search, Clause);
+}
+
+
+void prfs_InsertUsableClause(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A proof search object and a clause.
+  RETURNS: Nothing.
+  MEMORY:  The clause is assumed to be unshared.
+  EFFECT:  The clause is inserted into the usable sharing index
+           and list of <Search> sorted with respect to their weight. 
+	   The unshared literals are deleted.
+***************************************************************/
+{
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, prfs_Store(Search), prfs_Precedence(Search)) ||
+      clause_GetFlag(Clause, WORKEDOFF)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In prfs_InsertUsableClause: Illegal input.");
+    misc_FinishErrorReport();
+  }
+  /* The invariant that no two clauses have the same clause number cannot  */
+  /* be guaranteed as long as e.g. several directly subsequent reductions */
+  /* are applied to a clause that eventually gets a greater split level.   */
+#endif 
+    
+  prfs_SetUsableClauses(Search,clause_InsertWeighed(Clause,
+						    prfs_UsableClauses(Search),
+						    prfs_Store(Search),
+						    prfs_Precedence(Search)));
+  clause_InsertIntoSharing(Clause, prfs_UsableSharingIndex(Search),
+			   prfs_Store(Search), prfs_Precedence(Search));
+}
+
+
+void prfs_InsertDocProofClause(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A proof search object and a clause.
+  RETURNS: Nothing.
+  MEMORY:  The clause is assumed to be unshared.
+  EFFECT:  The clause is inserted into the proof documentation sharing index.
+	   The unshared literals are deleted.
+***************************************************************/
+{ 
+#ifdef CHECK
+  if (!clause_IsClause(Clause, prfs_Store(Search), prfs_Precedence(Search))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In prfs_InsertDocProofClause: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif   
+  
+  if (prfs_DocProofSharingIndex(Search) == (SHARED_INDEX)NULL)
+    clause_Delete(Clause);
+  else {
+    prfs_SetDocProofClauses(Search,list_Cons(Clause, prfs_DocProofClauses(Search)));
+    clause_InsertIntoSharing(Clause, prfs_DocProofSharingIndex(Search),
+			     prfs_Store(Search), prfs_Precedence(Search));
+  }
+}
+
+
+void prfs_MoveUsableWorkedOff(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A proof search object and a clause.
+  RETURNS: Nothing.
+  EFFECT:  The clause is inserted into the worked off sharing index
+           and list and it is deleted from the usable index and list.
+	   In particular, the WorkedOff flag is set and if <Clause> is a 
+	   declaration clause, it is inserted into the respective sort theories.
+***************************************************************/
+{
+#ifdef CHECK
+  if (!clause_IsClause(Clause,prfs_Store(Search), prfs_Precedence(Search)) ||
+      clause_GetFlag(Clause, WORKEDOFF)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In prfs_MoveUsableWorkedOff: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif 
+
+  prfs_SetUsableClauses(Search,list_PointerDeleteElement(prfs_UsableClauses(Search),Clause));
+  clause_SetFlag(Clause,WORKEDOFF);
+  clause_MoveSharedClause(Clause, prfs_UsableSharingIndex(Search),
+			  prfs_WorkedOffSharingIndex(Search), prfs_Store(Search),
+			  prfs_Precedence(Search));
+  prfs_SetWorkedOffClauses(Search,list_Cons(Clause, prfs_WorkedOffClauses(Search)));
+  prfs_InsertInSortTheories(Search, Clause);
+}
+
+
+void prfs_MoveWorkedOffDocProof(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A proof search object and a clause.
+  RETURNS: Nothing.
+  EFFECT:  The clause is inserted into the doc proof sharing index
+           and list of <Search> and it is deleted from the worked off
+	   index and list.
+***************************************************************/
+{
+#ifdef CHECK
+  if (!clause_IsClause(Clause, prfs_Store(Search), prfs_Precedence(Search)) ||
+      !clause_GetFlag(Clause, WORKEDOFF)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In prfs_MoveWorkedOffDocProof: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif 
+
+  prfs_DeleteFromSortTheories(Search, Clause);
+  prfs_SetWorkedOffClauses(Search,list_PointerDeleteElement(prfs_WorkedOffClauses(Search),Clause));
+  clause_RemoveFlag(Clause,WORKEDOFF);
+
+  if (prfs_DocProofSharingIndex(Search) == (SHARED_INDEX)NULL)
+    clause_DeleteFromSharing(Clause,prfs_WorkedOffSharingIndex(Search),
+			     prfs_Store(Search), prfs_Precedence(Search));
+  else {
+    clause_MoveSharedClause(Clause, prfs_WorkedOffSharingIndex(Search),
+			    prfs_DocProofSharingIndex(Search),prfs_Store(Search),
+			    prfs_Precedence(Search));
+    prfs_SetDocProofClauses(Search,list_Cons(Clause, prfs_DocProofClauses(Search)));
+  }
+}
+
+
+void prfs_MoveUsableDocProof(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A proof search object and a clause.
+  RETURNS: Nothing.
+  EFFECT:  The clause is inserted into the doc proof sharing index
+           and list of <Search> and it is deleted from the usable
+	   index and list.
+***************************************************************/
+{
+#ifdef CHECK
+  if (!clause_IsClause(Clause, prfs_Store(Search), prfs_Precedence(Search)) ||
+      clause_GetFlag(Clause, WORKEDOFF)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In prfs_MoveUsableDocProof: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif 
+
+  prfs_SetUsableClauses(Search,list_PointerDeleteElement(prfs_UsableClauses(Search),Clause));
+
+  if (prfs_DocProofSharingIndex(Search) == (SHARED_INDEX)NULL)
+    clause_DeleteFromSharing(Clause, prfs_UsableSharingIndex(Search),
+			     prfs_Store(Search), prfs_Precedence(Search));
+  else {
+    clause_MoveSharedClause(Clause, prfs_UsableSharingIndex(Search),
+			    prfs_DocProofSharingIndex(Search),prfs_Store(Search),
+			    prfs_Precedence(Search));
+    prfs_SetDocProofClauses(Search,list_Cons(Clause, prfs_DocProofClauses(Search)));
+  }
+}
+
+
+void prfs_MoveInvalidClausesDocProof(PROOFSEARCH Search)
+/**************************************************************
+  INPUT:   A proof search object.
+  RETURNS: Nothing.
+  EFFECT:  All clauses that have a split level higher than the
+           current split level of <Search> are moved to the
+	   proof documentation index. If it does not exist, i.e.,
+	   no proof documentation required, the clauses are
+	   deleted.
+***************************************************************/
+{
+  LIST   scan, invalid;
+  CLAUSE clause;
+
+  invalid = list_Nil();
+  for (scan = prfs_WorkedOffClauses(Search); !list_Empty(scan);
+       scan = list_Cdr(scan)) {
+    clause = (CLAUSE)list_Car(scan);
+    if (!prfs_IsClauseValid(clause, prfs_ValidLevel(Search)))
+      invalid = list_Cons(clause,invalid);
+  }
+  /* WARNING: The following move operation changes the worked off */
+  /* set of the proof search object destructively.                */
+  /* So it's impossible to move those function calls into the     */
+  /* loop above.                                                  */
+  for ( ; !list_Empty(invalid); invalid = list_Pop(invalid))
+    prfs_MoveWorkedOffDocProof(Search,list_Car(invalid));
+
+  invalid = list_Nil();
+  for (scan = prfs_UsableClauses(Search); !list_Empty(scan);
+       scan = list_Cdr(scan)) {
+    clause = (CLAUSE)list_Car(scan);
+    if (!prfs_IsClauseValid(clause, prfs_ValidLevel(Search)))
+      invalid = list_Cons(clause,invalid);
+  }
+  /* WARNING: The following move operation changes the usable     */
+  /* set of the proof search object destructively.                */
+  /* So it's impossible to move those function calls into the     */
+  /* loop above.                                                  */
+  for ( ; !list_Empty(invalid); invalid = list_Pop(invalid))
+    prfs_MoveUsableDocProof(Search,list_Car(invalid));
+}
+
+
+void prfs_ExtractWorkedOff(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A proof search object and a clause.
+  RETURNS: Nothing.
+  EFFECT:  The clause is removed from the worked off index and
+           list and returned as an unshared clause.
+	   Sort theories are updated accordingly.
+***************************************************************/
+{
+#ifdef CHECK
+  if (!clause_IsUnorderedClause(Clause) || !clause_GetFlag(Clause, WORKEDOFF)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In prfs_ExtractWorkedOff: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  prfs_DeleteFromSortTheories(Search, Clause);
+  clause_RemoveFlag(Clause,WORKEDOFF);
+  prfs_SetWorkedOffClauses(Search,list_PointerDeleteElement(prfs_WorkedOffClauses(Search),Clause));
+  clause_MakeUnshared(Clause,prfs_WorkedOffSharingIndex(Search));
+}
+
+
+void prfs_ExtractUsable(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A proof search object and a clause.
+  RETURNS: Nothing.
+  EFFECT:  The clause is removed from the usable off index and
+           list and returned as an unshared clause.
+***************************************************************/
+{
+#ifdef CHECK
+  if (!clause_IsUnorderedClause(Clause) || clause_GetFlag(Clause, WORKEDOFF)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In prfs_ExtractUsable: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif 
+
+  prfs_SetUsableClauses(Search,list_PointerDeleteElement(prfs_UsableClauses(Search),Clause));
+  clause_MakeUnshared(Clause,prfs_UsableSharingIndex(Search));
+}
+
+
+void prfs_ExtractDocProof(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A proof search object and a clause.
+  RETURNS: Nothing.
+  EFFECT:  The clause is removed from the docproof off index and
+           list and returned as an unshared clause.
+***************************************************************/
+{
+#ifdef CHECK
+  if (!clause_IsUnorderedClause(Clause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In prfs_ExtractDocProof: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif 
+
+  prfs_SetDocProofClauses(Search,list_PointerDeleteElement(prfs_DocProofClauses(Search),Clause));
+  clause_MakeUnshared(Clause,prfs_DocProofSharingIndex(Search));
+}
+
+
+void prfs_DeleteWorkedOff(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A proof search object and a clause.
+  RETURNS: Nothing.
+  EFFECT:  The clause is deleted from the worked off index and list.
+	   Sort theories are updated accordingly.
+***************************************************************/
+{
+#ifdef CHECK
+  if (!clause_IsClause(Clause, prfs_Store(Search), prfs_Precedence(Search)) ||
+      !clause_GetFlag(Clause, WORKEDOFF)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In prfs_DeleteWorkedOff: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif 
+
+  prfs_DeleteFromSortTheories(Search, Clause);
+  prfs_SetWorkedOffClauses(Search,list_PointerDeleteElement(prfs_WorkedOffClauses(Search),Clause));
+  clause_DeleteFromSharing(Clause, prfs_WorkedOffSharingIndex(Search),
+			   prfs_Store(Search), prfs_Precedence(Search));
+}
+
+
+void prfs_DeleteUsable(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A proof search object and a clause.
+  RETURNS: Nothing.
+  EFFECT:  The clause is deleted from the usable index and list.
+***************************************************************/
+{
+#ifdef CHECK
+  if (!clause_IsClause(Clause, prfs_Store(Search), prfs_Precedence(Search)) ||
+      clause_GetFlag(Clause, WORKEDOFF)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In prfs_DeleteUsable: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif 
+
+  prfs_SetUsableClauses(Search,list_PointerDeleteElement(prfs_UsableClauses(Search),Clause));
+  clause_DeleteFromSharing(Clause,prfs_UsableSharingIndex(Search),
+			   prfs_Store(Search), prfs_Precedence(Search));
+}
+
+
+void prfs_PrintSplit(SPLIT Split)
+/**************************************************************
+  INPUT:   A split.
+  RETURNS: Nothing.
+  EFFECT:  Prints the information kept in the split structure.
+***************************************************************/
+{
+  LIST Scan;
+
+  printf("\n Split: %d %ld", prfs_SplitSplitLevel(Split), (long)Split);
+  fputs("\n Father: ", stdout);
+  if (prfs_SplitFatherClause(Split) != (CLAUSE)NULL)
+    clause_Print(prfs_SplitFatherClause(Split));
+  else
+    fputs("No father, unnecessary split.", stdout);
+  
+  fputs("\n Split is ", stdout);
+  if (prfs_SplitIsUnused(Split))
+    puts("unused.");
+  else
+    puts("used.");
+  fputs(" Blocked clauses:", stdout);
+  for (Scan=prfs_SplitBlockedClauses(Split);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    putchar('\n');
+    putchar(' ');
+    clause_Print(list_Car(Scan));
+  }
+  fputs("\n Deleted clauses:", stdout);
+  for (Scan=prfs_SplitDeletedClauses(Split);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    putchar('\n');
+    putchar(' ');
+    clause_Print(list_Car(Scan));
+  }
+}
+
+
+void prfs_PrintSplitStack(PROOFSEARCH PS)
+/**************************************************************
+  INPUT:   A proof search object.
+  RETURNS: Nothing.
+  EFFECT:  Prints almost all the information kept in the
+           split stack structure.
+***************************************************************/
+{
+  LIST Scan;
+
+  fputs("\n Splitstack:", stdout);
+
+  for (Scan = prfs_SplitStack(PS); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    prfs_PrintSplit(list_Car(Scan));
+    fputs("\n---------------------", stdout);
+  }
+}
+
+
+void prfs_Print(PROOFSEARCH Search)
+/**************************************************************
+  INPUT:   A proof search object.
+  RETURNS: void.
+  EFFECT:  The proof search object is printed to stdout.
+***************************************************************/
+{
+  LIST Scan;
+
+#ifdef CHECK
+  if (!prfs_Check(Search)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In prfs_Print: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif 
+
+  printf("\n\n Proofsearch: Current Level: %d Last Backtrack Level: %d Splits: %d Loops: %d Backtracked: %d",
+	 prfs_ValidLevel(Search),prfs_LastBacktrackLevel(Search),prfs_SplitCounter(Search),
+	 prfs_Loops(Search),prfs_BacktrackedClauses(Search));
+  if (prfs_NonTrivClauseNumber(Search)>0)
+    printf("\n Clause %d implies a non-trivial domain.", prfs_NonTrivClauseNumber(Search));
+  else
+    fputs("\n Potentially trivial domain.", stdout);
+  fputs("\n Empty Clauses:", stdout);
+  for (Scan=prfs_EmptyClauses(Search);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    fputs("\n ", stdout);
+    clause_Print(list_Car(Scan));
+  }
+  fputs("\n Definitions:", stdout);
+  for (Scan=prfs_Definitions(Search);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    putchar('\n');
+    putchar(' ');
+    term_Print(list_Car(Scan));
+  }
+  fputs("\n Worked Off Clauses:", stdout);
+  for (Scan=prfs_WorkedOffClauses(Search);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    putchar('\n');
+    putchar(' ');
+    clause_Print(list_Car(Scan));
+  }
+  fputs("\n Usable Clauses:", stdout);
+  for (Scan=prfs_UsableClauses(Search);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    putchar('\n');
+    putchar(' ');
+    clause_Print(list_Car(Scan));
+  }
+  fputs("\n Finite predicates:", stdout);
+  for (Scan=prfs_GetFinMonPreds(Search);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    fputs("\n  ", stdout);
+    symbol_Print((SYMBOL)list_PairFirst(list_Car(Scan)));
+    fputs(": ", stdout);
+    term_TermListPrintPrefix(list_PairSecond(list_Car(Scan)));
+  }
+  prfs_PrintSplitStack(Search);
+  fputs("\n Static Sort Theory:", stdout);
+  sort_TheoryPrint(prfs_StaticSortTheory(Search));
+  fputs("\n Dynamic Sort Theory:", stdout);
+  sort_TheoryPrint(prfs_DynamicSortTheory(Search));
+  fputs("\n Approximated Dynamic Sort Theory:", stdout);
+  sort_TheoryPrint(prfs_ApproximatedDynamicSortTheory(Search));
+  putchar('\n');
+}
+
+
+CLAUSE prfs_DoSplitting(PROOFSEARCH PS, CLAUSE SplitClause, LIST Literals)
+/**************************************************************
+  INPUT:   An proof search object, an unshared clause to be splitted
+           where 'Literals' is the list of literals to keep (in their
+	   order in the SplitClause).
+  RETURNS: A pointer to the (stack-, not sharing-) inserted splitted clause.
+  MEMORY:  The blocked parts and the actparts literals are created
+           unshared, memory for the two (more for HornSplits) new 
+	   clausenodes is allocated.
+  EFFECT:  A new SPLIT object is created on the split stack of the proof
+           search object. The clause for the right branch will get clause
+           number 0 to make it distinguishable from the negation clauses,
+	   which get clause number -1.
+           All newly created clauses are influenced by some flags of the
+           internal flag store of the proof search object.
+	   For example the maximal literals are influenced by
+	   the weight of function symbols, which is defined by the
+	   flag "flag_FUNCWEIGHT".
+***************************************************************/
+{
+
+  SPLIT   NewSplit;
+  CLAUSE  NewClause, BlockedClause;
+  LITERAL NextLit,NewLit;
+  int     i,j,lengthBlocked,lengthNew,lc,la,ls,nc,na,ns;
+
+#ifdef CHECK
+  if (list_Empty(Literals) ||
+      !clause_IsClause(SplitClause, prfs_Store(PS), prfs_Precedence(PS))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In prfs_DoSplitting: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  prfs_DecSplitCounter(PS);
+  NewSplit = prfs_SplitCreate(PS);
+
+  prfs_SplitSetFatherClause(NewSplit, SplitClause);
+
+  lengthNew = list_Length(Literals);
+  lengthBlocked = clause_Length(SplitClause) - lengthNew;
+
+  NewClause = clause_CreateBody(lengthNew);          /* The left  clause */
+  BlockedClause = clause_CreateBody(lengthBlocked);  /* The right clause */
+  clause_DecreaseCounter(); /* reset internally increased counter! */
+  clause_SetNumber(BlockedClause, 0);
+  /* To detect forgotten setting at insertion! */
+
+  lc = clause_LastConstraintLitIndex(SplitClause);
+  la = clause_LastAntecedentLitIndex(SplitClause);
+  ls = clause_LastSuccedentLitIndex(SplitClause);
+
+  nc = na = ns = 0;
+
+  j = clause_FirstLitIndex();
+
+  for (i = clause_FirstLitIndex(); i <= ls; i++) {
+    NextLit = clause_GetLiteral(SplitClause, i);
+
+    NewLit  = clause_LiteralCopy(NextLit);
+
+    if ((lengthNew > 0) && /* To avoid access of Nirvana. */
+	list_PointerMember(Literals, NextLit)) {
+      /* NewLit is literal for the NewClause. */
+
+      lengthNew--;
+      clause_SetLiteral(NewClause, j++, NewLit);
+      clause_LiteralSetOwningClause(NewLit, NewClause);
+      clause_AddParentClause(NewClause, clause_Number(SplitClause));
+      clause_AddParentLiteral(NewClause, i);
+      if (i <= lc)
+	nc++;
+      else if (i <= la)
+	na++;
+      else 
+	ns++;
+
+    } else { /* NewLit is literal for the BlockedClause. */
+
+      clause_SetLiteral(BlockedClause, (i-j), NewLit);
+      clause_LiteralSetOwningClause(NewLit, BlockedClause);
+      clause_AddParentClause(BlockedClause, clause_Number(SplitClause));
+      clause_AddParentLiteral(BlockedClause, i);
+    }
+  } /* end of 'for all literals'. */
+
+  clause_SetNumOfConsLits(NewClause, nc);
+  clause_SetNumOfConsLits(BlockedClause,
+			  (clause_NumOfConsLits(SplitClause) - nc));
+  clause_SetNumOfAnteLits(NewClause, na);
+  clause_SetNumOfAnteLits(BlockedClause,
+			  (clause_NumOfAnteLits(SplitClause) - na));
+  clause_SetNumOfSuccLits(NewClause, ns);
+  clause_SetNumOfSuccLits(BlockedClause,
+			  (clause_NumOfSuccLits(SplitClause) - ns));
+
+  clause_ReInit(BlockedClause, prfs_Store(PS), prfs_Precedence(PS));
+  clause_UpdateSplitDataFromNewSplitting(BlockedClause, SplitClause,
+					 prfs_SplitSplitLevel(NewSplit));
+  clause_SetFromSplitting(BlockedClause);
+  clause_SetParentLiterals(BlockedClause,
+			   list_NReverse(clause_ParentLiterals(BlockedClause)));
+
+  clause_SetDepth(BlockedClause, clause_Depth(SplitClause)+1);
+
+  prfs_SplitAddBlockedClause(NewSplit, BlockedClause);
+  prfs_SplitSetDeletedClauses(NewSplit, list_Nil());
+
+  
+  prfs_SplitStackPush(PS, NewSplit);
+
+  clause_ReInit(NewClause, prfs_Store(PS), prfs_Precedence(PS));
+  clause_UpdateSplitDataFromNewSplitting(NewClause, SplitClause,
+					 prfs_SplitSplitLevel(NewSplit));
+  clause_SetFromSplitting(NewClause);
+
+  clause_SetParentLiterals(NewClause,
+			   list_NReverse(clause_ParentLiterals(NewClause)));
+
+  clause_SetDepth(NewClause, clause_Depth(SplitClause)+1);
+  clause_RemoveFlag(NewClause, WORKEDOFF);
+
+  if (clause_IsGround(NewClause)) {
+    /* Keep Clauses made from NewClause for refutation case! */
+    CLAUSE UnitClause;
+    LIST   AtomList;
+
+    la = clause_LastAntecedentLitIndex(NewClause);
+    ls = clause_LastSuccedentLitIndex(NewClause);
+
+    Literals = clause_ParentLiterals(NewClause);
+
+    for (i = clause_FirstLitIndex(); i <= ls; i++) {
+
+      NextLit    = clause_GetLiteral(NewClause, i);
+      AtomList   = list_List(term_Copy(clause_LiteralAtom(NextLit)));
+
+      if (i <= la)
+	UnitClause = clause_Create(list_Nil(), list_Nil(), AtomList,
+				   prfs_Store(PS), prfs_Precedence(PS));
+      else
+	UnitClause = clause_Create(list_Nil(), AtomList, list_Nil(),
+				   prfs_Store(PS), prfs_Precedence(PS));
+
+      clause_SetNumber(UnitClause, -1);
+      /* To detect forgotten setting at reinsertion! */
+      clause_DecreaseCounter();
+      /* Reset internally increased counter! */
+
+      list_Delete(AtomList);
+
+      clause_SetFromSplitting(UnitClause);
+      clause_UpdateSplitDataFromNewSplitting(UnitClause, SplitClause,
+					     prfs_SplitSplitLevel(NewSplit));
+      clause_AddParentClause(UnitClause, clause_Number(NewClause));
+      clause_AddParentLiteral(UnitClause, i);
+      clause_AddParentClause(UnitClause, clause_Number(SplitClause));
+      clause_AddParentLiteral(UnitClause, (int)list_Car(Literals));
+      Literals = list_Cdr(Literals);
+      prfs_SplitAddBlockedClause(NewSplit, UnitClause);
+    }
+  }
+  /* fputs("\n\nSPLITTING DONE!",stdout);
+     fputs("\nAus           : ",stdout); clause_Print(SplitClause); fflush(stdout);
+     fputs("\nDer erste Teil: ",stdout); clause_Print(NewClause); fflush(stdout);
+     fputs("\nDer zweite Teil: ",stdout);
+     clause_Print(BlockedClause); fflush(stdout);
+     puts("\nDaher als BlockedClauses:");
+     clause_ListPrint(prfs_SplitBlockedClauses(NewSplit)); fflush(stdout);
+  */
+  return NewClause;
+}
+
+
+static LIST prfs_GetSplitLiterals(PROOFSEARCH PS, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A Clause and a proofsearch object
+  RETURNS: A list of literals building the bigger part of a 
+           variable-disjunct literal partition if one exists,
+	   an empty list, else.
+  MEMORY:  Allocates memory for the literal list.
+***************************************************************/
+{
+  LITERAL NextLit;
+  int     i, length, OldLength;
+  LIST    LitList, VarOcc, NextOcc;
+  BOOL    Change;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, prfs_Store(PS), prfs_Precedence(PS))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In prfs_GetSplitLiterals: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif 
+
+  LitList = list_Nil();
+
+  if (prfs_SplitCounter(PS) != 0) {
+
+    if (clause_HasSuccLits(Clause)) {
+      if (clause_HasGroundSuccLit(Clause)) {
+
+	NextLit = clause_GetGroundSuccLit(Clause);
+	LitList = list_Cons(NextLit, LitList);
+
+	for (i = clause_LastAntecedentLitIndex(Clause);i >= clause_FirstLitIndex();i--) {
+	  NextLit = clause_GetLiteral(Clause, i);
+	  if (term_IsGround(clause_LiteralAtom(NextLit)))
+	    LitList = list_Cons(NextLit, LitList);
+	}
+	return LitList;
+      }
+
+      /* Clause has no ground succedent literals, but > 1 non-ground */
+      NextLit = clause_GetLiteral(Clause, clause_LastSuccedentLitIndex(Clause));
+      VarOcc  = term_VariableSymbols(clause_LiteralAtom(NextLit));
+      LitList = list_List(NextLit);
+      length  = clause_Length(Clause);
+      Change  = TRUE;
+
+      while (Change) {
+	Change = FALSE;
+
+	for (i=clause_LastSuccedentLitIndex(Clause)-1; i>=clause_FirstLitIndex(); i--) {
+
+	  NextLit = clause_GetLiteral(Clause, i);
+	
+	  if (!list_PointerMember(LitList, NextLit)) {
+	    NextOcc = term_VariableSymbols(clause_LiteralAtom(NextLit));
+	    if (list_HasIntersection(VarOcc, NextOcc)) { 
+	      OldLength = list_Length(VarOcc);
+	      VarOcc    = list_NPointerUnion(VarOcc, NextOcc);
+	      LitList   = list_Cons(NextLit, LitList);
+	      if (OldLength != list_Length(VarOcc))
+		Change = TRUE;
+	    }
+	    else
+	      list_Delete(NextOcc);
+	  }
+	}
+      }
+      if (list_Length(LitList) == length) {
+	list_Delete(LitList);
+	LitList = list_Nil();
+      }
+      Change = TRUE;    /* Check whether not all succedent literals are used */
+      for (i = clause_FirstSuccedentLitIndex(Clause); i < length && Change; i++)
+	if (!list_PointerMember(LitList,clause_GetLiteral(Clause, i)))
+	  Change = FALSE;
+      if (Change) {
+	list_Delete(LitList);
+	LitList = list_Nil();
+      }
+      list_Delete(VarOcc);
+    }
+  }
+  return LitList;
+}
+
+
+CLAUSE prfs_PerformSplitting(PROOFSEARCH Search, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A proof search object and an unshared clause.
+  EFFECT:  If <Clause> can be split it is splitted, the first
+           part of the split is returned  and the
+	   splitted clause is kept in the split stack.
+	   Otherwise <Clause> remains unchanged and NULL is returned.
+  RETURNS: NULL if <Clause> is not splittable, the first split part otherwise.
+***************************************************************/
+{
+  CLAUSE Result;
+
+  Result = (CLAUSE)NULL;
+  
+  if (clause_HasSolvedConstraint(Clause)) {
+    LIST LitList;
+
+    LitList = prfs_GetSplitLiterals(Search, Clause);
+
+    if (!list_Empty(LitList)) {
+      Result = prfs_DoSplitting(Search, Clause, LitList);
+      list_Delete(LitList);
+    }
+  }
+
+  return Result;
+}
+
+
+void prfs_InstallFiniteMonadicPredicates(PROOFSEARCH Search, LIST Clauses,
+					 LIST Predicates)
+/**************************************************************
+  INPUT:   A proof search object a list of clauses and a list
+           of monadic predicates.
+  RETURNS: Nothing.
+  EFFECT:  The argument terms for <Predicates> that occur in
+           positive unit clauses are extracted from <Clauses>
+           and installed in <Search> as an assoc list.
+***************************************************************/
+{
+  LIST   Pair, Scan, Result;
+  CLAUSE Clause;
+  TERM   Atom;
+
+  Result = list_Nil();
+
+  for (Scan=Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Clause = (CLAUSE)list_Car(Scan);
+    if (clause_Length(Clause) == 1 &&
+	clause_NumOfSuccLits(Clause) == 1) {
+      Atom = clause_GetLiteralAtom(Clause,clause_FirstSuccedentLitIndex(Clause));
+      if (list_PointerMember(Predicates, (POINTER)term_TopSymbol(Atom))) {
+	Pair = list_AssocListPair(Result, (POINTER)term_TopSymbol(Atom));
+	if (Pair != list_PairNull())
+	  list_PairRplacSecond(Pair, list_Cons(term_Copy(term_FirstArgument(Atom)),list_PairSecond(Pair)));
+	else
+	  Result = list_AssocCons(Result, (POINTER)term_TopSymbol(Atom), 
+				  list_List(term_Copy(term_FirstArgument(Atom))));
+      }
+    }
+  }
+  
+  prfs_DeleteFinMonPreds(Search);
+  prfs_SetFinMonPreds(Search, Result);
+}
+
+
+NAT prfs_GetNumberOfInstances(PROOFSEARCH Search, LITERAL Literal, BOOL Usables)
+/**************************************************************
+  INPUT:   A proof search object, a literal, and a boolean flag.
+  RETURNS: The number of instances of the literal's atom.
+  EFFECT:  
+***************************************************************/
+{
+  TERM         Atom;
+  NAT          NrOfInstances;
+  SHARED_INDEX WOIndex, UsIndex;
+
+  Atom = clause_LiteralAtom(Literal);
+  WOIndex = prfs_WorkedOffSharingIndex(Search);
+  UsIndex = prfs_UsableSharingIndex(Search);
+  NrOfInstances = sharing_GetNumberOfInstances(Atom, WOIndex);
+  if (Usables)
+    NrOfInstances += sharing_GetNumberOfInstances(Atom, UsIndex);
+
+  if (fol_IsEquality(Atom)) {
+    /* Exchange the subterms of the equation, and count the instances, too */
+    Atom = term_Create(fol_Equality(), list_Reverse(term_ArgumentList(Atom)));
+
+    NrOfInstances += sharing_GetNumberOfInstances(Atom, WOIndex);
+    if (Usables)
+      NrOfInstances += sharing_GetNumberOfInstances(Atom, UsIndex);
+
+    list_Delete(term_ArgumentList(Atom));
+    term_Free(Atom);
+
+    /* If equation is oriented, consider instances of the greater side, too */
+    Atom = clause_LiteralAtom(Literal);
+    if (clause_LiteralIsOrientedEquality(Literal)) {
+      NrOfInstances += sharing_GetNumberOfInstances(term_FirstArgument(Atom),
+						    WOIndex);
+      if (Usables)
+	NrOfInstances += sharing_GetNumberOfInstances(term_FirstArgument(Atom),
+						      UsIndex);
+    }
+  }
+    
+  return NrOfInstances;
+}
diff --git a/test/spass/search.h b/test/spass/search.h
new file mode 100644
index 0000000000000000000000000000000000000000..c34eb8abf353c3413f163a8df34f65937738ae10
--- /dev/null
+++ b/test/spass/search.h
@@ -0,0 +1,522 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *          REPRESENTATION OF PROOF SEARCH                * */
+/* *                                                        * */
+/* *  $Module:   PROOF SEARCH                               * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1997, 1998, 1999, 2000                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _PROOFSEARCH_
+#define _PROOFSEARCH_
+
+#include "clause.h"
+#include "sort.h"
+
+/**************************************************************/
+/* Data Structures and Constants                              */
+/**************************************************************/
+
+/* <blockedClauses>: list of (unshared) clauses containing the   */
+/*                   "remainder" of the clause splitted at this  */
+/*                   level and the negation of the first branch  */
+/*                   if this branch created a ground clause.     */ 
+/*                   The right clause has clause number 0, and   */
+/*                   the negation clauses have number -1.        */
+/* <deletedClauses>: list of (unshared) clauses made redundant   */
+/*                   by a clause of this level. The split level  */
+/*                   of these clauses may be above or below the  */
+/*                   current level, but not equal to the current */
+/*                   level.                                      */
+/* <father>:         the unshared clause that was splitted.      */
+typedef struct {
+  /* == 0 -> TOPLEVEL, 1,2,... */
+  int     splitlevel;
+  BOOL    used;
+  LIST    blockedClauses, deletedClauses;
+  CLAUSE  father;
+} *SPLIT, SPLIT_NODE;
+
+
+typedef struct PROOFSEARCH_HELP {
+  LIST            definitions;
+  LIST            emptyclauses;
+  LIST            usedemptyclauses;
+  LIST            finmonpreds;
+  SHARED_INDEX    woindex;
+  LIST            wolist;
+  SHARED_INDEX    usindex;
+  LIST            uslist;
+  SORTTHEORY      astatic;
+  SORTTHEORY      adynamic;
+  SORTTHEORY      dynamic;
+  SHARED_INDEX    dpindex;
+  LIST            dplist;
+  PRECEDENCE      precedence;
+  FLAGSTORE       store;
+  LIST            stack;
+  int             validlevel;
+  int             lastbacktrack;
+  int             splitcounter;
+  int             keptclauses;
+  int             derivedclauses;
+  int             loops;
+  int             backtracked;
+  NAT             nontrivclausenumber;
+} PROOFSEARCH_NODE,*PROOFSEARCH;
+
+/* There are two sets of clauses with their respective clause list: worked-off clauses   */
+/* contained in <woindex>, <wolist> and usable clauses, contained in <usindex>,<uslist>. */
+/* The assoc list <finitepreds> is a list of pairs (<pred>.(<gterm1>,...,<gtermn>))      */
+/* where <pred> (monadic) has (at most) the extension <gterm1>,...,<gtermn>              */
+/* Three sort theories: <astatic> is the static overall approximation, only available    */
+/* in a non-equality setting, <adynamic> is the dynamic approximation only considering   */
+/* maximal declarations, and <dynamic> is the (not approximated) dynamic sort theory of  */
+/* all maximal declarations. Clauses that are no longer needed for the search, but for   */
+/* proof documentation are stored in <dpindex>, <dplist>. If <dpindex> is NULL, then     */
+/* this means that no proof documentation is required.                                   */
+/* A search is also heavily influenced by the used <precedence> and flag values in       */
+/* store.                                                                                */
+/* The next components deal with splitting: the split stack, the current level           */
+/* of splitting, the last backtrack level (for branch condensing) and the overall number */
+/* of splittings stored in <splitcounter>.                                               */
+/* Finally some statistics is stored: the number of kept, derived clauses ...            */
+/* and the clause number of some clause that implies a non-trivial domain .               */
+
+/**************************************************************/
+/* Inline Functions                                           */
+/**************************************************************/
+
+static __inline__ LIST prfs_EmptyClauses(PROOFSEARCH Prf)
+{
+  return Prf->emptyclauses;
+}
+
+static __inline__ void prfs_SetEmptyClauses(PROOFSEARCH Prf, LIST Clauses)
+{
+  Prf->emptyclauses = Clauses;
+}
+
+static __inline__ LIST prfs_Definitions(PROOFSEARCH Prf)
+{
+  return Prf->definitions;
+}
+
+static __inline__ void prfs_SetDefinitions(PROOFSEARCH Prf, LIST Definitions)
+{
+  Prf->definitions = Definitions;
+}
+
+static __inline__ LIST prfs_UsedEmptyClauses(PROOFSEARCH Prf)
+{
+  return Prf->usedemptyclauses;
+}
+
+static __inline__ void prfs_SetUsedEmptyClauses(PROOFSEARCH Prf, LIST Clauses)
+{
+  Prf->usedemptyclauses = Clauses;
+}
+
+
+static __inline__ LIST prfs_WorkedOffClauses(PROOFSEARCH Prf)
+{
+  return Prf->wolist;
+}
+
+static __inline__ void prfs_SetWorkedOffClauses(PROOFSEARCH Prf, LIST Clauses)
+{
+  Prf->wolist = Clauses;
+}
+
+static __inline__ SHARED_INDEX prfs_WorkedOffSharingIndex(PROOFSEARCH Prf)
+{
+  return Prf->woindex;
+}
+
+static __inline__ LIST prfs_UsableClauses(PROOFSEARCH Prf)
+{
+  return Prf->uslist;
+}
+
+static __inline__ void prfs_SetUsableClauses(PROOFSEARCH Prf, LIST Clauses)
+{
+  Prf->uslist = Clauses;
+}
+
+static __inline__ SHARED_INDEX prfs_UsableSharingIndex(PROOFSEARCH Prf)
+{
+  return Prf->usindex;
+}
+
+static __inline__ LIST prfs_DocProofClauses(PROOFSEARCH Prf)
+{
+  return Prf->dplist;
+}
+
+static __inline__ void prfs_SetDocProofClauses(PROOFSEARCH Prf, LIST Clauses)
+{
+  Prf->dplist = Clauses;
+}
+
+static __inline__ SHARED_INDEX prfs_DocProofSharingIndex(PROOFSEARCH Prf)
+{
+  return Prf->dpindex;
+}
+
+static __inline__ void prfs_AddDocProofSharingIndex(PROOFSEARCH Prf)
+{
+  Prf->dpindex  = sharing_IndexCreate();
+}
+
+static __inline__ LIST prfs_GetFinMonPreds(PROOFSEARCH Prf)
+{
+  return Prf->finmonpreds;
+}
+
+static __inline__ void prfs_SetFinMonPreds(PROOFSEARCH Prf, LIST Preds)
+{
+  Prf->finmonpreds = Preds;
+}
+
+static __inline__ void prfs_DeleteFinMonPreds(PROOFSEARCH Prf)
+{
+  list_DeleteAssocListWithValues(Prf->finmonpreds,
+				 (void (*)(POINTER)) term_DeleteTermList);
+  prfs_SetFinMonPreds(Prf, list_Nil());
+}
+
+static __inline__ SORTTHEORY prfs_StaticSortTheory(PROOFSEARCH Prf)
+{
+  return Prf->astatic;
+}
+
+static __inline__ void prfs_SetStaticSortTheory(PROOFSEARCH Prf, SORTTHEORY Theory)
+{
+  Prf->astatic = Theory;
+}
+
+static __inline__ SORTTHEORY prfs_DynamicSortTheory(PROOFSEARCH Prf)
+{
+  return Prf->dynamic;
+}
+
+static __inline__ void prfs_SetDynamicSortTheory(PROOFSEARCH Prf, SORTTHEORY Theory)
+{
+  Prf->dynamic = Theory;
+}
+
+static __inline__ SORTTHEORY prfs_ApproximatedDynamicSortTheory(PROOFSEARCH Prf)
+{
+  return Prf->adynamic;
+}
+
+static __inline__ void prfs_SetApproximatedDynamicSortTheory(PROOFSEARCH Prf, SORTTHEORY Theory)
+{
+  Prf->adynamic = Theory;
+}
+
+static __inline__ PRECEDENCE prfs_Precedence(PROOFSEARCH Prf)
+{
+  return Prf->precedence;
+}
+
+static __inline__ FLAGSTORE prfs_Store(PROOFSEARCH Prf)
+{
+  return Prf->store;
+}
+
+static __inline__ BOOL prfs_SplitLevelCondition(NAT OriginLevel, NAT RedundantLevel, NAT BacktrackLevel)
+{
+  return (OriginLevel > RedundantLevel || OriginLevel > BacktrackLevel);
+}
+
+static __inline__ BOOL prfs_IsClauseValid(CLAUSE C, int Level)
+{
+  return clause_SplitLevel(C) <= Level;
+}
+
+static __inline__ SPLIT prfs_GetSplitOfLevel(int L, PROOFSEARCH Prf)
+{
+  LIST Scan;
+  Scan = Prf->stack; 
+  while (!list_Empty(Scan) &&
+	 (((SPLIT)list_Car(Scan))->splitlevel != L))
+    Scan = list_Cdr(Scan);  
+  
+  return (SPLIT) list_Car(Scan);
+}
+
+static __inline__ LIST prfs_SplitStack(PROOFSEARCH Prf)
+{
+  return Prf->stack;
+}
+
+static __inline__ SPLIT prfs_SplitStackTop(PROOFSEARCH Prf)
+{
+  return (SPLIT) list_Car(Prf->stack);
+}
+
+static __inline__ void prfs_SplitStackPop(PROOFSEARCH Prf)
+{
+  Prf->stack = list_Pop(Prf->stack);
+}
+
+static __inline__ void prfs_SplitStackPush(PROOFSEARCH Prf, SPLIT S)
+{
+  Prf->stack = list_Cons(S, Prf->stack);
+}
+
+static __inline__ BOOL prfs_SplitStackEmpty(PROOFSEARCH Prf)
+{
+  return list_StackEmpty(prfs_SplitStack(Prf));
+}
+
+static __inline__ int prfs_TopLevel(void) 
+{
+  return 0;
+}
+
+static __inline__ int prfs_ValidLevel(PROOFSEARCH Prf)
+{
+  return Prf->validlevel;
+}
+
+static __inline__ void prfs_SetValidLevel(PROOFSEARCH Prf, int Value)
+{
+  Prf->validlevel = Value;
+}
+
+static __inline__ void prfs_IncValidLevel(PROOFSEARCH Prf)
+{
+  (Prf->validlevel)++;
+}
+
+static __inline__ void prfs_DecValidLevel(PROOFSEARCH Prf)
+{
+  (Prf->validlevel)--;
+}
+
+static __inline__ int prfs_LastBacktrackLevel(PROOFSEARCH Prf)
+{
+  return Prf->lastbacktrack;
+}
+
+static __inline__ void prfs_SetLastBacktrackLevel(PROOFSEARCH Prf, int Value)
+{
+  Prf->lastbacktrack = Value;
+}
+
+static __inline__ int prfs_SplitCounter(PROOFSEARCH Prf)
+{
+  return Prf->splitcounter;
+}
+
+static __inline__ void prfs_SetSplitCounter(PROOFSEARCH Prf, int c)
+{
+  Prf->splitcounter = c;
+}
+
+static __inline__ void prfs_DecSplitCounter(PROOFSEARCH Prf)
+{
+  (Prf->splitcounter)--;
+}
+
+static __inline__ int prfs_KeptClauses(PROOFSEARCH Prf)
+{
+  return Prf->keptclauses;
+}
+
+static __inline__ void prfs_IncKeptClauses(PROOFSEARCH Prf)
+{
+  Prf->keptclauses++;
+}
+
+static __inline__ int prfs_DerivedClauses(PROOFSEARCH Prf)
+{
+  return Prf->derivedclauses;
+}
+
+static __inline__ void prfs_IncDerivedClauses(PROOFSEARCH Prf, int k)
+{
+  Prf->derivedclauses += k;
+}
+
+static __inline__ int prfs_Loops(PROOFSEARCH Prf)
+{
+  return Prf->loops;
+}
+
+static __inline__ void prfs_SetLoops(PROOFSEARCH Prf, int k)
+{
+  Prf->loops = k;
+}
+
+static __inline__ void prfs_DecLoops(PROOFSEARCH Prf)
+{
+  Prf->loops--;
+}
+
+static __inline__ int prfs_BacktrackedClauses(PROOFSEARCH Prf)
+{
+  return Prf->backtracked;
+}
+
+static __inline__ void prfs_SetBacktrackedClauses(PROOFSEARCH Prf, int k)
+{
+  Prf->backtracked = k;
+}
+
+static __inline__ void prfs_IncBacktrackedClauses(PROOFSEARCH Prf, int k)
+{
+  Prf->backtracked += k;
+}
+
+static __inline__ NAT prfs_NonTrivClauseNumber(PROOFSEARCH Prf)
+{
+  return Prf->nontrivclausenumber;
+}
+
+static __inline__ void prfs_SetNonTrivClauseNumber(PROOFSEARCH Prf, NAT Number)
+{
+  Prf->nontrivclausenumber = Number;
+}
+
+
+/**************************************************************/
+/* Functions for accessing SPLIT objects                      */
+/**************************************************************/
+
+static __inline__ void prfs_SplitFree(SPLIT Sp)
+{
+  memory_Free(Sp, sizeof(SPLIT_NODE));
+}
+
+static __inline__ LIST prfs_SplitBlockedClauses(SPLIT S)
+{
+  return S->blockedClauses;
+}
+
+static __inline__ void prfs_SplitAddBlockedClause(SPLIT S, CLAUSE C)
+{
+  S->blockedClauses = list_Cons(C,S->blockedClauses);
+}
+
+static __inline__ void prfs_SplitSetBlockedClauses(SPLIT S, LIST L)
+{
+  S->blockedClauses = L;
+}
+
+static __inline__ LIST prfs_SplitDeletedClauses(SPLIT S)
+{
+  return S->deletedClauses;
+}
+
+static __inline__ void prfs_SplitSetDeletedClauses(SPLIT S, LIST L)
+{
+  S->deletedClauses = L;
+}
+
+static __inline__ int prfs_SplitSplitLevel(SPLIT S)
+{
+  return S->splitlevel;
+}
+
+static __inline__ BOOL prfs_SplitIsUsed(SPLIT S)
+{
+  return S->used;
+}
+
+static __inline__ BOOL prfs_SplitIsUnused(SPLIT S)
+{
+  return !S->used;
+}
+
+static __inline__ void prfs_SplitSetUsed(SPLIT S)
+{
+  S->used = TRUE;
+}
+
+static __inline__ CLAUSE prfs_SplitFatherClause(SPLIT S) 
+{
+  return S->father;
+}
+
+static __inline__ void prfs_SplitSetFatherClause(SPLIT S, CLAUSE C)
+{
+  S->father = C;
+}
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+PROOFSEARCH prfs_Create(void);
+BOOL        prfs_Check(PROOFSEARCH);
+void        prfs_CopyIndices(PROOFSEARCH, PROOFSEARCH);
+void        prfs_Delete(PROOFSEARCH);
+void        prfs_DeleteDocProof(PROOFSEARCH);
+void        prfs_Clean(PROOFSEARCH);
+void        prfs_Print(PROOFSEARCH);
+void        prfs_PrintSplit(SPLIT);
+void        prfs_PrintSplitStack(PROOFSEARCH);
+void        prfs_InsertWorkedOffClause(PROOFSEARCH,CLAUSE);
+void        prfs_InsertUsableClause(PROOFSEARCH,CLAUSE);
+void        prfs_InsertDocProofClause(PROOFSEARCH,CLAUSE);
+void        prfs_MoveUsableWorkedOff(PROOFSEARCH, CLAUSE);
+void        prfs_MoveWorkedOffDocProof(PROOFSEARCH, CLAUSE);
+void        prfs_MoveUsableDocProof(PROOFSEARCH, CLAUSE);
+void        prfs_ExtractWorkedOff(PROOFSEARCH, CLAUSE);
+void        prfs_DeleteWorkedOff(PROOFSEARCH, CLAUSE);
+void        prfs_ExtractUsable(PROOFSEARCH, CLAUSE);
+void        prfs_DeleteUsable(PROOFSEARCH, CLAUSE);
+void        prfs_ExtractDocProof(PROOFSEARCH, CLAUSE);
+void        prfs_MoveInvalidClausesDocProof(PROOFSEARCH);
+void        prfs_SwapIndexes(PROOFSEARCH);
+
+void        prfs_InstallFiniteMonadicPredicates(PROOFSEARCH, LIST, LIST);
+
+CLAUSE      prfs_PerformSplitting(PROOFSEARCH, CLAUSE);
+CLAUSE      prfs_DoSplitting(PROOFSEARCH, CLAUSE, LIST);
+NAT         prfs_GetNumberOfInstances(PROOFSEARCH, LITERAL, BOOL);
+
+
+#endif
diff --git a/test/spass/sharing.c b/test/spass/sharing.c
new file mode 100644
index 0000000000000000000000000000000000000000..47f8b501793568db835f58f627ebfc2150a969cf
--- /dev/null
+++ b/test/spass/sharing.c
@@ -0,0 +1,1143 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                  STRUCTURE SHARING                     * */
+/* *                                                        * */
+/* *  $Module:   SHARING                                    * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000            * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "sharing.h"
+
+/**************************************************************/
+/* Static Variables                                           */
+/**************************************************************/
+
+#ifdef CHECK
+static BOOL sharing_DATABLOCKED;
+#endif
+
+static LIST sharing_DATALIST = (LIST) NULL;
+
+#define sharing_STACKSIZE      500
+static LIST sharing_STACK[sharing_STACKSIZE];
+static LIST* sharing_STACKPOINTER = sharing_STACK;
+
+/**************************************************************/
+/* Prototypes for static functions used only in this module   */
+/**************************************************************/
+
+static BOOL sharing_IsNoMoreUsed(TERM);
+static LIST sharing_InternGetDataList(TERM);
+
+static TERM sharing_InsertIntoSharing(TERM, SHARED_INDEX);
+static void sharing_DeleteFromSharing(TERM, SHARED_INDEX);
+
+static void sharing_ResetTermStamp(TERM);
+
+static void sharing_PrintWithSuperterms(TERM);
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *			                                    * */
+/* *  PRIMITIVE SHARING FUNCTIONS                           * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+SHARED_INDEX sharing_IndexCreate(void)
+/**********************************************************
+  INPUT:   None.
+  RETURNS: A shared index, consisting of an Index, a Consttable
+           and a Vartable.
+  EFFECTS: Initializes the shared Index for the sharing_Vartable and the
+           sharing_Consttable with NULL-Pointers and an empty st_index.
+**********************************************************/
+{
+  SHARED_INDEX Result;
+  int          i;
+
+  Result = (SHARED_INDEX)memory_Malloc(sizeof(SHARED_INDEX_NODE));
+  sharing_SetIndex(Result, st_IndexCreate());
+
+  for (i=0; (i < symbol_MaxVars()); i++)
+    sharing_SetVartableEntry(Result, i, NULL);
+
+  for (i=0; (i < symbol_MaxConsts()); i++)
+    sharing_SetConsttableEntry(Result, i, NULL);
+
+  sharing_SetStampID(Result, term_GetStampID());
+  return Result;
+}
+
+
+void sharing_IndexDelete(SHARED_INDEX ShIndex)
+/**********************************************************
+  INPUT:   A shared Index.
+  RETURNS: None.
+  EFFECTS: Deletes the Index and frees the memory for the
+           structure including the Const- and Vartable.
+**********************************************************/
+{
+  st_IndexDelete(sharing_Index(ShIndex));
+
+  memory_Free(ShIndex, sizeof(SHARED_INDEX_NODE));
+}
+
+
+void sharing_PushOnStack(TERM Term)
+/**********************************************************
+  INPUT:   A term.
+  RETURNS: None.
+  EFFECTS: Creates a Stack of Pointers to the 
+           term and all of its subterms in their order in
+	   the arglist (thus ordered by depth).
+	   top of the stack is bottom term
+**********************************************************/
+{
+  LIST ArgList;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sharing_PushOnStack: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  stack_Push(Term);
+
+  ArgList = term_ArgumentList(Term);
+
+  while (!list_Empty(ArgList)){
+    sharing_PushOnStack(list_Car(ArgList));
+    ArgList = list_Cdr(ArgList);
+  }
+}
+
+
+void sharing_PushReverseOnStack(TERM Term)
+/**********************************************************
+  INPUT:   A term.
+  RETURNS: None.
+  EFFECTS: Creates a Stack of Pointers to the 
+           term and all of its subterms, except variables in their order in
+	   the arglist (thus ordered by depth).
+	   top of the stack is top term
+**********************************************************/
+{
+  LIST ArgList;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sharing_PushReverseOnStack: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (!term_IsVariable(Term)) {
+
+    ArgList = term_ArgumentList(Term);
+
+    while (!list_Empty(ArgList)){
+      sharing_PushReverseOnStack(list_Car(ArgList));
+      ArgList = list_Cdr(ArgList);
+    }
+
+    stack_Push(Term);
+  }
+}
+
+void sharing_PushReverseOnStackExcept(TERM Term, LIST DontTermList)
+/**********************************************************
+  INPUT:   A term and an exception list.
+  RETURNS: None.
+  EFFECTS: Creates a Stack of Pointers to the 
+           term and all of its subterms that are not contained
+	   or below the terms in DontTermList in their order in
+	   the arglist (thus ordered by depth).
+	   top of the stack is top term
+**********************************************************/
+{
+  LIST ArgList;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sharing_PushReverseOnStack: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (!term_IsVariable(Term) && !term_ListContainsTerm(DontTermList, Term)) {
+    ArgList = term_ArgumentList(Term);
+
+    while (!list_Empty(ArgList)){
+      sharing_PushReverseOnStackExcept(list_Car(ArgList), DontTermList);
+      ArgList = list_Cdr(ArgList);
+    }
+
+    stack_Push(Term);
+  }
+}
+
+void sharing_PushOnStackNoStamps(TERM Term)
+/**********************************************************
+  INPUT:   A term.
+  RETURNS: None.
+  EFFECTS: Creates a Stack of Pointers to the 
+           term and all of its subterms that are not stamped
+	   or below stamped terms.
+	   top of the stack is top term.
+**********************************************************/
+{
+  LIST ArgList;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sharing_PushReverseOnStackNoStamps: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (!term_IsVariable(Term) && !term_HasTermStamp(Term)) {
+
+    stack_Push(Term);
+
+    ArgList = term_ArgumentList(Term);
+
+    while (!list_Empty(ArgList)){
+      sharing_PushOnStackNoStamps(list_Car(ArgList));
+      ArgList = list_Cdr(ArgList);
+    }
+  }
+}
+
+
+void sharing_PushListOnStack(LIST TermList)
+/**********************************************************
+  INPUT:   A list of terms.
+  RETURNS: None.
+  EFFECTS: Creates a Stack of Pointers to the 
+           terms in <TermList>  and all of subterms in their order in
+	   the arglist (thus ordered by depth).
+**********************************************************/
+{
+  while (!list_Empty(TermList)) {
+    sharing_PushOnStack(list_Car(TermList));
+    TermList = list_Cdr(TermList);
+  }
+}
+
+
+void sharing_PushListReverseOnStack(LIST TermList)
+/**********************************************************
+  INPUT:   A list of terms.
+  RETURNS: None.
+  EFFECTS: Puts all terms in Termlist and their superterms
+           in their order in the arglist (thus ordered by depth)
+	   on the stack.
+	   On top of the stack are subterms.
+**********************************************************/
+{
+  while (!list_Empty(TermList)) {
+    sharing_PushReverseOnStack(list_Car(TermList));
+    TermList = list_Cdr(TermList);
+  }
+}
+
+void sharing_PushListReverseOnStackExcept(LIST TermList, LIST DontPushList)
+/**********************************************************
+  INPUT:   Two lists of terms.
+  RETURNS: None.
+  EFFECTS: Puts all terms in Termlist except those contained in
+           DontPushList and their superterms
+           in their order in the arglist (thus ordered by depth)
+	   on the stack.
+	   On top of the stack are subterms.
+**********************************************************/
+{
+  while (!list_Empty(TermList)) {
+    sharing_PushReverseOnStackExcept(list_Car(TermList), DontPushList);
+    TermList = list_Cdr(TermList);
+  }
+}
+
+void sharing_PushListOnStackNoStamps(LIST TermList)
+/**********************************************************
+  INPUT:   A list of terms.
+  RETURNS: None.
+  EFFECTS: Puts all terms in Termlist on the stack.
+	   On top of the stack are subterms.
+**********************************************************/
+{
+  while (!list_Empty(TermList)) {
+    sharing_PushOnStackNoStamps(list_Car(TermList));
+    TermList = list_Cdr(TermList);
+  }
+}
+
+
+static BOOL sharing_IsNoMoreUsed(TERM Term)
+/**********************************************************
+  INPUT:   A term.
+  RETURNS: TRUE,  if the Term has no superterms,
+           FALSE, else.
+**********************************************************/
+{
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sharing_IsNoMoreUsed: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  return (list_Empty(term_SupertermList(Term)));
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *			                                    * */
+/* *  FUNCTIONS FOR INSERTION AND DELETION                  * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+/**************************************************************/
+/* ********************************************************** */
+/* *			                                    * */
+/* *  1) FUNCTIONS FOR INSERTION                            * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+TERM sharing_Insert(POINTER Data, TERM Atom, SHARED_INDEX SharedIndex)
+/**********************************************************
+  INPUT:   A data element, it's unshared atom and a SharedIndex.
+  RETURNS: The shared term inserted into the SharedIndex.
+  CAUTION: The superterm slot of <Atom> is destructively used!
+  MEMORY:  The term 'Atom' still exists, memory needed for
+           the shared version is allocated. 
+**********************************************************/
+{
+#ifdef CHECK
+  if (!term_IsTerm(Atom) || (!sharing_IsNoMoreUsed(Atom))){
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sharing_Insert: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Atom = sharing_InsertIntoSharing(Atom, SharedIndex);
+
+  term_RplacSupertermList(Atom, list_Cons(Data, term_SupertermList(Atom)));
+
+  return(Atom);
+}
+
+
+static TERM sharing_InsertIntoSharing(TERM Term, SHARED_INDEX SharedIndex)
+/**********************************************************
+  INPUT:   A term and a shared index.
+  RETURNS: A copy of 'Term' which is inserted into the Sharing
+           and the "SharedIndex".
+  MEMORY:  The unshared version isn't freed, needed memory
+           is allocated.
+**********************************************************/
+{
+  int B_Stack;
+  TERM InsTerm;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sharing_InsertIntoSharing: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  B_Stack = stack_Bottom();
+  sharing_PushOnStack(Term);
+  InsTerm = stack_Top();      /* not necessary initialization ... */
+
+  while (! stack_Empty(B_Stack)){
+    InsTerm = stack_PopResult();
+
+    if (term_IsVariable(InsTerm)){
+      if (!sharing_IsSharedVar(InsTerm, SharedIndex)) {
+
+	sharing_SetVartableEntry(SharedIndex, sharing_VariableIndex(InsTerm),
+				 term_Create(term_TopSymbol(InsTerm),
+					     list_Nil()));
+
+	st_EntryCreate(sharing_Index(SharedIndex),
+		       sharing_VartableEntry(SharedIndex,
+					     sharing_VariableIndex(InsTerm)),
+		       sharing_VartableEntry(SharedIndex,
+					     sharing_VariableIndex(InsTerm)),
+		       cont_LeftContext());
+      }
+
+	/* The NULL-Pointer in the Vartable is replaced by a copy of the */
+	/* InsTerm, which is referenced by the InsTerms SharedTermCopy.  */
+	/* A complex T still has to be insert. into its Args superlists. */
+	/* The unshared Term isn't yet in the 'SharedIndex' and thus is  */
+	/* inserted, too.                                                */
+    
+
+      sharing_RememberSharedTermCopy(InsTerm,
+				     sharing_VartableEntry(SharedIndex, sharing_VariableIndex(InsTerm)));
+
+    }else if (term_IsConstant(InsTerm)){ 
+      if (!sharing_IsSharedConst(InsTerm, SharedIndex)) { 
+	sharing_SetConsttableEntry(SharedIndex, sharing_ConstantIndex(InsTerm),
+				   term_Create(term_TopSymbol(InsTerm),
+					       list_Nil()));
+
+	st_EntryCreate(sharing_Index(SharedIndex),
+		       sharing_ConsttableEntry(SharedIndex, sharing_ConstantIndex(InsTerm)),
+		       sharing_ConsttableEntry(SharedIndex, sharing_ConstantIndex(InsTerm)),
+		       cont_LeftContext());
+      }
+
+	/* The NULL-Pointer in the Consttable is replaced by a copy of the */
+	/* InsTerm, which is referenced by the InsTerms SharedTermCopy.    */
+	/* A complex T still has to be insert. into its Args superlists.   */
+	/* The unshared Term isn't yet in the 'SharedIndex' and thus is    */
+	/* inserted, too.                                                  */
+
+      sharing_RememberSharedTermCopy(InsTerm,
+				     sharing_ConsttableEntry(SharedIndex, sharing_ConstantIndex(InsTerm)));
+
+    }else{  /* term_IsComplex(InsTerm) */
+            /* -> owns subterms which now have copies in Sharing.  */
+
+      TERM SharedDuplicate;
+      LIST HelpList;
+      BOOL DuplCandHasSameArgs;
+
+      SharedDuplicate = (TERM)NULL;
+      HelpList =
+        term_SupertermList(sharing_SharedTermCopy(term_FirstArgument(InsTerm)));
+      if (list_Empty(HelpList)){
+	  SharedDuplicate = term_Create(term_TopSymbol(InsTerm), list_Nil());
+	  DuplCandHasSameArgs = FALSE;
+	}
+      else{
+	DuplCandHasSameArgs = FALSE;
+	while (!DuplCandHasSameArgs && !list_Empty(HelpList)){
+	  SharedDuplicate = (TERM) list_First(HelpList);
+
+	  if (term_TopSymbol(SharedDuplicate) == term_TopSymbol(InsTerm)){
+	    LIST OrigHelpArgList, DuplHelpArgList;
+
+	    OrigHelpArgList = term_ArgumentList(InsTerm);
+	    DuplHelpArgList = term_ArgumentList(SharedDuplicate);
+	    while (!list_Empty(OrigHelpArgList) &&
+		   (DuplCandHasSameArgs = 
+                   (sharing_SharedTermCopy(list_First(OrigHelpArgList)) ==
+		    list_First(DuplHelpArgList)))){
+	      DuplHelpArgList = list_Cdr(DuplHelpArgList);
+	      OrigHelpArgList = list_Cdr(OrigHelpArgList);
+	    }
+	  }
+	  HelpList = list_Cdr(HelpList);
+	}
+	if (!DuplCandHasSameArgs)
+	  SharedDuplicate = term_Create(term_TopSymbol(InsTerm), list_Nil());
+      } /* end of else fuer Behandlung von InsTerm mit shared FirstArg. */
+
+      if (!DuplCandHasSameArgs){
+      /* Falls neue Kopie gemacht wurde, wird diese hier "eingeshared": */
+
+	for (HelpList = term_ArgumentList(InsTerm); !list_Empty(HelpList);
+	     HelpList = list_Cdr(HelpList)){
+	  TERM SharedArg;
+	
+	  SharedArg = sharing_SharedTermCopy((TERM)list_First(HelpList));
+
+	  term_RplacArgumentList(SharedDuplicate, 
+				 list_Cons(SharedArg,
+					   term_ArgumentList(SharedDuplicate)));
+
+	  term_RplacSupertermList(SharedArg,
+	    list_Cons(SharedDuplicate,
+		      term_SupertermList(SharedArg)));
+	}
+	term_RplacArgumentList(SharedDuplicate, 
+	  list_NReverse(term_ArgumentList(SharedDuplicate)));
+	
+	/* Now a newly generated term can be inserted into the 'SharedIndex' !  */
+	
+	st_EntryCreate(sharing_Index(SharedIndex),
+		       SharedDuplicate,
+		       SharedDuplicate,
+		       cont_LeftContext());
+
+      }
+      sharing_RememberSharedTermCopy(InsTerm,
+				      SharedDuplicate);
+    } 
+  } 
+
+  return(sharing_SharedTermCopy(InsTerm));
+}
+
+/**************************************************************/
+/* ********************************************************** */
+/* *			                                    * */
+/* *  2) FUNCTIONS FOR DELETION                             * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+void sharing_Delete(POINTER Data, TERM Atom, SHARED_INDEX SharedIndex)
+/**********************************************************
+  INPUT:   A data element, its atom and an index.
+  RETURNS: Nothing.
+  MEMORY:  Destructive, deletes 'Atom' from Sharing and frees
+           memory that's no more needed.
+***********************************************************/
+{
+#ifdef CHECK
+  if (!term_IsTerm(Atom)){
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sharing_Delete: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  term_RplacSupertermList(Atom,
+    list_PointerDeleteElement(term_SupertermList(Atom), Data));
+
+  if (sharing_IsNoMoreUsed(Atom))
+    sharing_DeleteFromSharing(Atom, SharedIndex);
+
+}
+
+
+static void sharing_DeleteFromSharing(TERM Term, SHARED_INDEX SharedIndex)
+/**********************************************************
+  INPUT:   A term and a SharedIndex
+  RETURNS: Nothing 
+  MEMORY:  'Term' is removed from the Sharing, only correct
+           if 'Term' is unshared in sharing (real subterms
+	   may be shared, off course).
+***********************************************************/
+{
+  BOOL IsIndexed;
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sharing_DeleteFromSharing: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  IsIndexed = st_EntryDelete(sharing_Index(SharedIndex), Term, Term, cont_LeftContext());
+
+#ifdef CHECK
+  if (!IsIndexed) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sharing_DeleteFromSharing: Input not indexed.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (term_IsComplex(Term)){
+    LIST Args;
+
+    Args = term_ArgumentList(Term);
+
+    while (!list_Empty(Args)){
+      TERM NextArg;
+      LIST Help;
+
+      /* This block frees the terms arglists memory. */
+      Help = Args;
+      NextArg = (TERM) list_First(Args);
+      Args = list_Cdr(Args);
+      list_Free(Help);
+
+      term_RplacSupertermList(NextArg, 
+	list_PointerDeleteOneElement(term_SupertermList(NextArg), Term));
+      if (sharing_IsNoMoreUsed(NextArg))
+	sharing_DeleteFromSharing(NextArg, SharedIndex);
+    }
+
+  } else if (term_IsConstant(Term)) {
+    sharing_SetConsttableEntry(SharedIndex, sharing_ConstantIndex(Term), NULL);
+  } else {
+    sharing_SetVartableEntry(SharedIndex, sharing_VariableIndex(Term), NULL);
+  }
+  list_Delete(term_SupertermList(Term));
+  term_Free(Term);
+}
+
+
+/**************************************************************/
+/* Functions to access unshared data via the shared term.     */
+/**************************************************************/
+
+LIST sharing_GetDataList(TERM Term, SHARED_INDEX SharedIndex)
+/**********************************************************
+  INPUT:   A shared term and the shared index it belongs to.
+  RETURNS: The list of data connected to all superterms of Term,
+           e.g. the list of all literals containing Term.
+  EFFECT:  Allocates memory for the returned list.
+  CAUTION: Works recursive!
+**********************************************************/
+{
+  LIST Result = list_Nil();
+#ifdef CHECK
+  if (!term_IsTerm(Term) || (SharedIndex == NULL)){
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sharing_GetDataList: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  /* What if the term doesn't belong to this shared index ?????? */
+
+#endif
+
+  if (term_StampOverflow(sharing_StampID(SharedIndex)))
+    sharing_ResetAllTermStamps(SharedIndex);
+    
+  term_StartStamp();
+
+  Result = sharing_InternGetDataList(Term);
+
+  term_StopStamp();
+
+  return Result;
+}
+
+
+static LIST sharing_InternGetDataList(TERM Term)
+/**********************************************************
+  INPUT:   A shared term.
+  RETURNS: The list of data connected to all superterms of Term
+  EFFECT:  Allocates memory for the returned list.
+********************************************************/
+{
+  if (term_IsAtom(Term))
+    /* We are at top level of the superterm "tree",  */
+    /* so the recursion stops here                   */ 
+    return list_Copy(term_AtomsLiterals(Term));
+  else{
+    LIST SuperList;
+    LIST DataList = list_Nil();
+
+    for (SuperList = term_SupertermList(Term); !list_Empty(SuperList);
+	 SuperList = list_Cdr(SuperList)) {
+      TERM superterm = (TERM) list_Car(SuperList);
+      if (!term_AlreadyVisited(superterm)) {
+	DataList = list_Nconc(sharing_InternGetDataList(superterm), DataList);
+	term_SetTermStamp(superterm);
+      }
+    }
+    return DataList;
+  }
+}
+
+
+void sharing_StartDataIterator(TERM Term, SHARED_INDEX SharedIndex)
+/**********************************************************
+  INPUT:   A shared term and the shared index it belongs to.
+  RETURNS: Nothing.
+  EFFECT:  Prepares the data iterator for Term.
+           After this call you can access single data items
+	   for Term with function sharing_GetNextData.
+********************************************************/
+{
+#ifdef CHECK
+  if (!term_IsTerm(Term) || (SharedIndex == NULL)){
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sharing_StartDataIterator: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+  if (sharing_DATABLOCKED) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sharing_StartDataIterator: Data iterator already used.\n");
+    misc_FinishErrorReport();
+  }
+  sharing_DATABLOCKED = TRUE;
+#endif
+
+  if (term_StampOverflow(sharing_StampID(SharedIndex)))
+    sharing_ResetAllTermStamps(SharedIndex);
+  term_StartStamp();
+
+  /* Init stack */
+  sharing_STACKPOINTER = sharing_STACK;  /* Pop all items */
+  while (!term_IsAtom(Term)) {
+    /* Push superterm list on stack */
+    *(sharing_STACKPOINTER++) = term_SupertermList(Term);
+    Term                      = list_Car(term_SupertermList(Term));
+  }
+    
+  sharing_DATALIST = term_AtomsLiterals(Term);
+}
+
+
+POINTER sharing_GetNextData(void)
+/**********************************************************
+  INPUT:   None
+  RETURNS: A single data item connected to the term specified
+           in the previous call of sharing_StartDataIterator.
+	   NULL is returned, if all data items were accessed before.
+  EFFECT:  In contrast to function sharing_GetDataList
+           no memory is allocated.
+********************************************************/
+{
+  POINTER Result = NULL;
+  LIST superlist;
+
+#ifdef CHECK
+  if (!sharing_DATABLOCKED) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sharing_GetNextData: Iterator wasn't started.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (!list_Empty(sharing_DATALIST)) {
+    Result = list_Car(sharing_DATALIST);
+    sharing_DATALIST = list_Cdr(sharing_DATALIST);
+  } else {
+    superlist = NULL;
+    while ((sharing_STACKPOINTER > sharing_STACK) && /* stack not empty */
+	   list_Empty(superlist)) {
+      /* change between backtracking and expansion */
+      do { /* Backtracking */
+	superlist = *(--sharing_STACKPOINTER); /* PopResult */
+	term_SetTermStamp(list_Car(superlist));
+	do
+	  superlist = list_Cdr(superlist);
+	while (!list_Empty(superlist) &&
+	       term_AlreadyVisited(list_Car(superlist)));
+      } while ((sharing_STACKPOINTER>sharing_STACK) && list_Empty(superlist));
+      while (!list_Empty(superlist) &&
+	     !term_IsAtom(list_Car(superlist))) { /* Expansion */
+	*(sharing_STACKPOINTER++) = superlist;
+	superlist = term_SupertermList(list_Car(superlist));
+	/* Search next unvisited term */
+	while (!list_Empty(superlist) &&
+	       term_AlreadyVisited(list_Car(superlist)))
+	  superlist = list_Cdr(superlist);
+      }
+    }
+    if (!list_Empty(superlist)) {
+      *(sharing_STACKPOINTER++) = superlist;
+      sharing_DATALIST          = term_AtomsLiterals(list_Car(superlist));
+      Result                    = list_Car(sharing_DATALIST);
+      sharing_DATALIST          = list_Cdr(sharing_DATALIST);
+    }
+  } /* else */
+  return Result;
+}
+
+
+void sharing_StopDataIterator(void)
+/**********************************************************
+  INPUT:   None.
+  RETURNS: Nothing.
+  EFFECT:  The data iterator is stopped for the term you specified
+           in the corresponding call of sharing_StartDataIterator.
+********************************************************/
+{
+#ifdef CHECK
+  if (!sharing_DATABLOCKED) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sharing_StopDataIterator: Iterator wasn't started.\n");
+    misc_FinishErrorReport();
+  }
+  sharing_DATABLOCKED = FALSE;
+#endif
+  sharing_DATALIST = list_Nil();
+  term_StopStamp();
+}
+
+
+LIST sharing_NAtomDataList(TERM Atom)
+/**********************************************************
+  INPUT:   A shared term.
+  RETURNS: A List of data connected with 'Term' or superterms.
+  EFFECT:  No memory Allocation
+  CAUTION: THE RETURNED LIST MUST NOT CHANGE
+**********************************************************/
+{
+#ifdef CHECK
+  if (!term_IsTerm(Atom) || !term_IsAtom(Atom)){
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sharing_NAtomDataList: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  return(term_AtomsLiterals(Atom));
+}
+
+
+LIST sharing_GetAllSuperTerms(SHARED_INDEX Index)
+/**********************************************************
+  INPUT:   A shared Index.
+  RETURNS: A List of all Data in the shared Index.
+  EFFECT:  The term stamp is used.
+**********************************************************/
+{
+  int  i;
+  LIST Result = list_Nil();
+  TERM term;
+
+  if (term_StampOverflow(sharing_StampID(Index)))
+    sharing_ResetAllTermStamps(Index);
+  term_StartStamp();
+  
+  for (i = 0; i < symbol_MaxVars(); i++) {
+    term = sharing_VartableEntry(Index,i);
+    if (term != NULL)
+      Result = list_Nconc(sharing_InternGetDataList(term), Result);
+  }
+
+  for (i = 0; i < symbol_MaxConsts(); i++) {
+    term = sharing_ConsttableEntry(Index,i);
+    if (term != NULL)
+      Result = list_Nconc(sharing_InternGetDataList(term), Result);
+  }
+  
+  term_StopStamp();
+
+  return Result;
+}
+
+
+void sharing_ResetAllTermStamps(SHARED_INDEX SharedIndex)
+/**********************************************************
+  INPUT:   A shared index.
+  RETURNS: Nothing.
+  EFFECT:  The stamps of all terms in the shared index are reset.
+**********************************************************/
+{
+  TERM term;
+  int i;
+     
+  /* Reset stamp for all variables and their superterms */
+  for (i = 0; i < symbol_MaxVars(); i++) {
+    term = sharing_VartableEntry(SharedIndex, i);
+    if (term != NULL)
+      sharing_ResetTermStamp(term);
+  }
+
+  /* Reset stamp for all constants and their superterms */
+  for (i = 0; i < symbol_MaxConsts(); i++){
+    term = sharing_ConsttableEntry(SharedIndex, i);
+    if (term != NULL)
+      sharing_ResetTermStamp(term);
+  }
+}
+
+
+static void sharing_ResetTermStamp(TERM Term)
+/**********************************************************
+  INPUT:   A term.
+  RETURNS: Nothing.
+  EFFECT:  The stamps of Term and all its superterms are reset.
+**********************************************************/
+{
+  LIST SuperList;
+  TERM SuperTerm;
+
+  if (!term_IsAtom(Term)) {
+    for (SuperList = term_SupertermList(Term); !list_Empty(SuperList);
+	 SuperList = list_Cdr(SuperList)) {
+      SuperTerm = (TERM) list_Car(SuperList);
+      if (!term_StampAlreadyReset(SuperTerm)) {
+	sharing_ResetTermStamp(SuperTerm);
+	term_ResetTermStamp(SuperTerm);
+      }
+    }
+  }
+}
+
+
+NAT sharing_GetNumberOfOccurances(TERM Term)
+/**************************************************************
+  INPUT:   A shared (!) term.
+  RETURNS: How many literals contain <Term>.
+           Note that literals containing <Term> <n> times are counted
+	   <n> times.
+***************************************************************/
+{
+  if (term_IsAtom(Term))
+    /* Stop recursion */
+    return list_Length(term_AtomsLiterals(Term));
+  else {
+    LIST Scan;
+    NAT  Result;
+
+    Result = 0;
+    for (Scan = term_SupertermList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+      Result += sharing_GetNumberOfOccurances(list_Car(Scan));
+
+    return Result;
+  }
+}
+
+
+NAT sharing_GetNumberOfInstances(TERM Term, SHARED_INDEX Index)
+/**************************************************************
+  INPUT:   A (!) shared term and a shared index. The term has to be
+           part of the index.
+  RETURNS: How many literals within the index contain an instance of <Term>.
+           Note that literals containing <n> instances of <Term>
+	   are counted <n> times.
+***************************************************************/
+{
+  NAT  Result;
+  TERM Instance;
+
+  Result   = 0;
+  Instance = st_ExistInstance(cont_LeftContext(), sharing_Index(Index), Term);
+  while (Instance != NULL) {
+    Result += sharing_GetNumberOfOccurances(Instance);
+    Instance = st_NextCandidate();
+  }
+  return Result;
+}
+
+
+/**************************************************************/
+/* Output functions for the sharing structure.                  */
+/**************************************************************/
+
+void sharing_PrintVartable(SHARED_INDEX SharedIndex)
+/**********************************************************
+  INPUT:   A shared index.
+  RETURNS: Nothing.
+  EFFECT:  Prints the Vartable entries to stdout
+**********************************************************/
+{
+  int i;
+     
+  for (i = 0; i < symbol_MaxVars(); i++){
+    if (sharing_VartableEntry(SharedIndex, i) != NULL){
+      printf("\n X%d   :  ", i);
+      
+      term_Print(sharing_VartableEntry(SharedIndex, i));
+    }
+  }
+}
+
+
+void sharing_PrintConsttable(SHARED_INDEX SharedIndex)
+/**********************************************************
+  INPUT: A shared index.  
+  RETURNS: Nothing.
+  EFFECT:  Prints the Consttable entries to stdout
+**********************************************************/
+{
+  int i;
+     
+  for (i = 0; i < symbol_MaxConsts(); i++){
+    if (sharing_ConsttableEntry(SharedIndex, i) != NULL){
+      printf("\n c%d   :  ", i);
+      
+      term_Print(sharing_ConsttableEntry(SharedIndex, i));
+    }
+  }
+}
+
+
+void sharing_PrintSharingConstterms1(SHARED_INDEX SharedIndex)
+/**********************************************************
+  INPUT:   A shared index.
+  RETURNS: Nothing.
+  EFFECT:  Prints all terms from the Consttable and their
+           direct superterms to stdout
+**********************************************************/
+{
+  TERM term;
+  int i;
+     
+  for (i = 0; i < symbol_MaxConsts(); i++) {
+    term = sharing_ConsttableEntry(SharedIndex, i);
+    if (term != NULL){
+      printf("\n c%d   :  ", i);
+      term_Print(term);
+      puts("   has the direct superterms : ");
+      term_TermListPrint(term_SupertermList(term));
+    }
+  }
+}
+
+
+void sharing_PrintSharingVarterms1(SHARED_INDEX SharedIndex)
+/**********************************************************
+  INPUT:   A shared index.
+  RETURNS: Nothing.
+  EFFECT:  Prints all terms from the Vartable and their
+           superterms to stdout
+**********************************************************/
+{
+  TERM term;
+  int i;
+     
+  for (i = 0; i < symbol_MaxVars(); i++) {
+    term = sharing_VartableEntry(SharedIndex, i);
+    if (term != NULL){
+      printf("\n x%d   :  ", i);
+      term_Print(term);
+      puts("   has the direct superterms : ");
+      term_TermListPrint(term_SupertermList(term));
+    }
+  }
+}
+
+
+static void sharing_PrintWithSuperterms(TERM Term)
+/**********************************************************
+  INPUT:   A Term
+  RETURNS: Nothing.
+  EFFECT:  Prints all Superterms of 'Term' from the sharing
+           to stdout.
+**********************************************************/
+{
+
+  LIST HelpList;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sharing_PrintWithSuperterms: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (term_IsAtom(Term)) {
+    term_Print(Term);
+    putchar('\n');
+  }
+  else{
+    term_Print(Term);
+    HelpList = term_SupertermList(Term);
+    if (!list_Empty(HelpList)){
+      putchar('[');
+      term_TermListPrint(HelpList);
+      puts("]");
+      while (!list_Empty(HelpList)){
+	sharing_PrintWithSuperterms(list_Car(HelpList));
+	HelpList = list_Cdr(HelpList);
+      }
+    }
+  }
+}
+
+
+void sharing_PrintSharing(SHARED_INDEX SharedIndex)
+/**********************************************************
+  INPUT:   A shared Index.
+  EFFECT:  Prints the sharing to standard.out.
+**********************************************************/
+{
+  int i;
+     
+  for (i = 0; i < symbol_MaxConsts(); i++){
+    if (sharing_ConsttableEntry(SharedIndex, i) != NULL){
+      sharing_PrintWithSuperterms(sharing_ConsttableEntry(SharedIndex, i));
+      puts("\n");
+    }
+  }
+  puts("------------------------");
+  for (i = 0; i < symbol_MaxVars(); i++){
+    if (sharing_VartableEntry(SharedIndex, i) != NULL){
+      sharing_PrintWithSuperterms(sharing_VartableEntry(SharedIndex, i));
+      puts("\n");
+    }
+  }
+}
+
+
+void sharing_PrintSameLevelTerms(TERM Term)
+/**********************************************************
+  INPUT:   A term.
+  RETURNS: Nothing.
+  EFFECT:  Prints all terms, that share any of 'Term's args to 
+           standard.out.
+**********************************************************/
+{
+  LIST HelpList;
+
+  HelpList = term_ArgumentList(Term);
+
+  while (!list_Empty(HelpList)){
+    if (!list_Empty(term_SupertermList(list_First(HelpList))))
+      term_TermListPrint(term_SupertermList(list_First(HelpList)));
+
+    HelpList = list_Cdr(HelpList);
+  }
+}
+
+void sharing_PrintStack(void)
+/**********************************************************
+  INPUT:   None.
+  RETURNS: Nothing.
+  EFFECT:  Prints the internal sharing stack for iterative
+           queries. Only for debugging purposes.
+**********************************************************/
+{
+  TERM term;
+  LIST* ptr = sharing_STACKPOINTER;
+
+  while (ptr > sharing_STACK) {
+    ptr--;
+    term = list_Car(*ptr);
+    term_Print(term);
+    putchar('\n');
+  }
+}
+
+
diff --git a/test/spass/sharing.h b/test/spass/sharing.h
new file mode 100644
index 0000000000000000000000000000000000000000..d4f5d7e1dd6d2fb2d98e30b9c556da5f61756b41
--- /dev/null
+++ b/test/spass/sharing.h
@@ -0,0 +1,245 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                  STRUCTURE SHARING                     * */
+/* *                                                        * */
+/* *  $Module:   SHARING                                    * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 2000, 2001            * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _SHARING_
+#define _SHARING_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "term.h"
+#include "st.h"
+
+/**************************************************************/
+/* Data Structures and Constants                              */
+/**************************************************************/
+
+/* Symbol Tables; constants are just positive    */
+/* integers and variables negative integers.     */
+/* For constants and vars is a special symbol    */
+/* table available, containing the  sharing      */
+/* info, i.e. a POINTER to the term structure, if */
+/* the symbol is already inserted in the sharing */
+/* structure, a NULL Pointer else.               */
+  
+typedef TERM VARTABLE[symbol__MAXVARIABLES];
+
+typedef TERM CONSTTABLE[symbol__MAXSIGNATURE];
+
+typedef struct {
+  st_INDEX   index;
+  VARTABLE   vartable;
+  CONSTTABLE consttable;
+  NAT        stampId;
+} SHARED_INDEX_NODE, *SHARED_INDEX;
+
+/**************************************************************/
+/* Inline Functions                                           */
+/**************************************************************/
+
+static __inline__ st_INDEX sharing_Index(SHARED_INDEX ShIndex)
+{
+  return ShIndex->index;
+}
+
+static __inline__ void sharing_SetIndex(SHARED_INDEX ShIndex, st_INDEX ST)
+{
+  ShIndex->index = ST;
+}
+
+static __inline__ const TERM* sharing_Vartable(SHARED_INDEX ShIndex)
+{
+  return ShIndex->vartable;
+}
+
+static __inline__ const TERM* sharing_Consttable(SHARED_INDEX ShIndex)
+{
+  return ShIndex->consttable;
+}
+
+static __inline__ NAT sharing_StampID(SHARED_INDEX ShIndex)
+{
+  return ShIndex->stampId;
+}
+
+static __inline__ void sharing_SetStampID(SHARED_INDEX ShIndex, NAT Stamp)
+{
+  ShIndex->stampId = Stamp;
+}
+
+static __inline__ TERM sharing_VartableEntry(SHARED_INDEX ShIndex, NAT Index)
+{
+  return ShIndex->vartable[Index];
+}
+
+static __inline__ void sharing_SetVartableEntry(SHARED_INDEX ShIndex,
+						NAT Index, TERM Term)
+{
+  ShIndex->vartable[Index] = Term;
+}
+
+static __inline__ TERM sharing_ConsttableEntry(SHARED_INDEX ShIndex,
+					       NAT Index)
+{
+  return ShIndex->consttable[Index];
+}
+
+static __inline__ void sharing_SetConsttableEntry(SHARED_INDEX ShIndex,
+						 NAT Index, TERM Term)
+{
+  ShIndex->consttable[Index] = Term;
+}
+
+static __inline__ TERM sharing_GetVarFromSymbol(SYMBOL S, SHARED_INDEX ShIndex)
+{
+  return sharing_VartableEntry(ShIndex, symbol_VarIndex(S));
+}
+
+static __inline__ int sharing_VariableIndex(TERM Term)
+{
+  return symbol_VarIndex(term_TopSymbol(Term));
+}
+
+static __inline__ int sharing_ConstantIndex(TERM Term)
+{
+  return symbol_Index(term_TopSymbol(Term));
+}
+
+static __inline__ BOOL sharing_IsSharedVar(TERM T, SHARED_INDEX ShIndex)
+/* RETURNS: True if there's already an entry for the variable T   */
+/*          in the Vartable of the shared index ShIndex.          */
+{
+  return sharing_VartableEntry(ShIndex, sharing_VariableIndex(T)) != NULL;
+}
+
+static __inline__ BOOL sharing_IsSharedConst(TERM T, SHARED_INDEX ShIndex)
+/* True if there's already an entry for the constant T   */
+/* in the Consttable of the shared index ShIndex.        */
+{
+  return sharing_ConsttableEntry(ShIndex, sharing_ConstantIndex(T)) != NULL;
+}
+
+static __inline__ BOOL sharing_IsNotReallyShared(TERM Term)
+/* Der einzige Superterm ist der in dem ich loesche */
+{
+  return list_Length(term_SupertermList(Term)) <= 1;
+}
+
+static __inline__ void sharing_RememberSharedTermCopy(TERM Term, TERM Copy)
+/* The unshared term Term has now a link to its shared copy  */
+{
+  term_RplacSuperterm(Term, Copy);
+}
+
+static __inline__ TERM sharing_SharedTermCopy(TERM Term)
+/* Return the shared copy of the unshared term Term */
+{
+  return term_Superterm(Term);
+}
+
+
+/**************************************************************/
+/* Functions for Creation and Deletion of a SHARED_INDEX         */
+/**************************************************************/
+
+SHARED_INDEX sharing_IndexCreate(void); 
+void         sharing_IndexDelete(SHARED_INDEX);
+
+/**************************************************************/
+/* Functions on term insertion and deletion.                  */
+/**************************************************************/
+
+TERM         sharing_Insert(POINTER, TERM, SHARED_INDEX);
+void         sharing_Delete(POINTER, TERM, SHARED_INDEX);
+
+void         sharing_PushOnStack(TERM);
+void         sharing_PushReverseOnStack(TERM);
+void         sharing_PushOnStackNoStamps(TERM);
+void         sharing_PushListOnStack(LIST);
+void         sharing_PushListReverseOnStack(LIST);
+void         sharing_PushListReverseOnStackExcept(LIST, LIST);
+void         sharing_PushListOnStackNoStamps(LIST);
+
+/**************************************************************/
+/* Functions to access unshared data by the shared terms.     */
+/**************************************************************/
+
+LIST         sharing_GetDataList(TERM, SHARED_INDEX);
+
+void         sharing_StartDataIterator(TERM, SHARED_INDEX);
+POINTER      sharing_GetNextData(void);
+void         sharing_StopDataIterator(void);
+
+LIST         sharing_NAtomDataList(TERM);
+LIST         sharing_GetAllSuperTerms(SHARED_INDEX);
+
+void         sharing_ResetAllTermStamps(SHARED_INDEX);
+
+NAT          sharing_GetNumberOfOccurances(TERM);
+NAT          sharing_GetNumberOfInstances(TERM, SHARED_INDEX);
+
+/**************************************************************/
+/* Output functions                                            */
+/**************************************************************/
+
+void         sharing_PrintVartable(SHARED_INDEX);
+void         sharing_PrintConsttable(SHARED_INDEX);
+void         sharing_PrintSharing(SHARED_INDEX);
+
+/**************************************************************/
+/* Debugging Functions                                        */
+/**************************************************************/
+
+void         sharing_PrintStack(void);
+void         sharing_PrintSharingConstterms1(SHARED_INDEX);
+void         sharing_PrintSharingVarterms1(SHARED_INDEX);
+void         sharing_PrintSameLevelTerms(TERM);
+
+
+#endif
+
diff --git a/test/spass/small_problem.dfg b/test/spass/small_problem.dfg
new file mode 100644
index 0000000000000000000000000000000000000000..f0b1a6d1b1445e428f61f4c967ca992470793085
--- /dev/null
+++ b/test/spass/small_problem.dfg
@@ -0,0 +1,154 @@
+%------------------------------------------------------------------------------
+% File     : SET002+4 : TPTP v3.1.0. Released v2.2.0.
+% Domain   : Set Theory (Naive)
+% Problem  : Idempotency of union
+% Version  : [Pas99] axioms.
+% English  :
+
+% Refs     : [Pas99] Pastre (1999), Email to G. Sutcliffe
+% Source   : [Pas99]
+% Names    :
+
+% Status   : Theorem
+% Rating   : 0.36 v3.1.0, 0.56 v2.7.0, 0.33 v2.6.0, 0.57 v2.5.0, 0.50 v2.4.0, 0.25 v2.3.0, 0.00 v2.2.1
+% Syntax   : Number of formulae    :   12 (   2 unit)
+%            Number of atoms       :   30 (   3 equality)
+%            Maximal formula depth :    7 (   5 average)
+%            Number of connectives :   20 (   2 ~  ;   2  |;   4  &)
+%                                         (  10 <=>;   2 =>;   0 <=)
+%                                         (   0 <~>;   0 ~|;   0 ~&)
+%            Number of predicates  :    4 (   0 propositional; 2-2 arity)
+%            Number of functors    :    9 (   1 constant; 0-2 arity)
+%            Number of variables   :   29 (   0 singleton;  28 !;   1 ?)
+%            Maximal term depth    :    2 (   1 average)
+
+% Comments : 
+%          : tptp2X -f dfg -t rm_equality:rstfp SET002+4.p 
+%------------------------------------------------------------------------------
+
+begin_problem(TPTP_Problem).
+
+list_of_descriptions.
+name({*[ File     : SET002+4 : TPTP v3.1.0. Released v2.2.0.],[ Names    :]*}).
+author({*[ Source   : [Pas99]]*}).
+status(unknown).
+description({*[ Refs     : [Pas99] Pastre (1999), Email to G. Sutcliffe]*}).
+end_of_list.
+
+list_of_symbols.
+functions[(difference,2), (empty_set,0), (intersection,2), (power_set,1), (product,1), (singleton,1), (sum,1), (union,2), (unordered_pair,2)].
+predicates[(equal_set,2), (member,2), (subset,2)].
+end_of_list.
+
+list_of_formulae(axioms).
+
+formula(
+ forall([A,B],
+  equiv(
+   subset(A,B),
+   forall([X],
+    implies(
+     member(X,A),
+     member(X,B))))),
+subset ).
+
+formula(
+ forall([A,B],
+  equiv(
+   equal_set(A,B),
+   and(
+    subset(A,B),
+    subset(B,A)))),
+equal_set ).
+
+formula(
+ forall([X,A],
+  equiv(
+   member(X,power_set(A)),
+   subset(X,A))),
+power_set ).
+
+formula(
+ forall([X,A,B],
+  equiv(
+   member(X,intersection(A,B)),
+   and(
+    member(X,A),
+    member(X,B)))),
+intersection ).
+
+formula(
+ forall([X,A,B],
+  equiv(
+   member(X,union(A,B)),
+   or(
+    member(X,A),
+    member(X,B)))),
+union ).
+
+formula(
+ forall([X],
+  not(
+   member(X,empty_set))),
+empty_set ).
+
+formula(
+ forall([B,A,E],
+  equiv(
+   member(B,difference(E,A)),
+   and(
+    member(B,E),
+    not(
+     member(B,A))))),
+difference ).
+
+formula(
+ forall([X,A],
+  equiv(
+   member(X,singleton(A)),
+   equal(X,A))),
+singleton ).
+
+formula(
+ forall([X,A,B],
+  equiv(
+   member(X,unordered_pair(A,B)),
+   or(
+    equal(X,A),
+    equal(X,B)))),
+unordered_pair ).
+
+formula(
+ forall([X,A],
+  equiv(
+   member(X,sum(A)),
+   exists([Y],
+    and(
+     member(Y,A),
+     member(X,Y))))),
+sum ).
+
+formula(
+ forall([X,A],
+  equiv(
+   member(X,product(A)),
+   forall([Y],
+    implies(
+     member(Y,A),
+     member(X,Y))))),
+product ).
+
+end_of_list.
+
+%----NOTE WELL: conjecture has been negated
+list_of_formulae(conjectures).
+
+formula(  %(conjecture)
+ forall([A],
+  equal_set(union(A,A),A)),
+thI14 ).
+
+end_of_list.
+
+end_problem.
+%------------------------------------------------------------------------------
diff --git a/test/spass/sort.c b/test/spass/sort.c
new file mode 100644
index 0000000000000000000000000000000000000000..e109ef1323b8d3cf42b0c44ab677ef89ac1de596
--- /dev/null
+++ b/test/spass/sort.c
@@ -0,0 +1,1974 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                  SORTED REASONING                      * */
+/* *                                                        * */
+/* *  $Module:   SORT                                       * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "sort.h"
+
+/**************************************************************/
+/* Global Variables                                           */
+/**************************************************************/
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *			HIGH LEVEL FUNCTIONS		    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+void sort_Delete(SORT Sort)
+/**************************************************************
+  INPUT:   A sort.
+  RETURNS: Nothing.
+  MEMORY:  The memory of the sort is freed.
+***************************************************************/
+{
+  list_Delete(Sort);
+}
+
+BOOL sort_Eq(SORT S1, SORT S2)
+/**************************************************************
+  INPUT:   Two sorts.
+  RETURNS: TRUE iff the sorts <S1> and <S2> are the same base
+           sort intersection
+***************************************************************/
+{
+  LIST Scan1,Scan2;
+  BOOL Found;
+
+#ifdef CHECK
+  if (!sort_IsSort(S1) || !sort_IsSort(S2)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sort_Eq :");
+    misc_ErrorReport(" Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (list_Length(S1) !=  list_Length(S2))
+    return FALSE;
+
+  for (Scan1=S1; !list_Empty(Scan1); Scan1=list_Cdr(Scan1)) {
+    Found = FALSE;
+    for (Scan2=S2; !list_Empty(Scan2) && !Found; Scan2=list_Cdr(Scan2))
+      Found = sort_NodeEqual(list_Car(Scan1),list_Car(Scan2));
+    if (!Found)
+      return FALSE;
+  } 
+
+  return TRUE;
+}
+
+
+LIST sort_GetSymbolsFromSort(SORT Sort)
+/**************************************************************
+  INPUT:   A sort.
+  RETURNS: The list of sort symbols..
+***************************************************************/
+{
+  LIST result = list_Nil();
+
+  for ( ; !list_Empty(Sort); Sort = list_Cdr(Sort))
+    result = list_Cons((POINTER)sort_NodeSymbol(list_Car(Sort)), result);
+
+  return result;
+}
+
+BOOL sort_ContainsSymbol(SORT Sort, SYMBOL Symbol)
+/**************************************************************
+  INPUT:   A sort and a symbol.
+  RETURNS: TRUE, if the sort contains the symbol, FALSE otherwise.
+***************************************************************/
+{
+  for ( ; !list_Empty(Sort); Sort = list_Cdr(Sort))
+    if (symbol_Equal(sort_NodeSymbol(list_Car(Sort)), Symbol))
+      return TRUE;
+
+  return FALSE;
+}
+
+BOOL sort_IsSort(SORT Sort)
+/**************************************************************
+  INPUT:   A sort.
+  RETURNS: TRUE, if the sort contains not more than one node.
+***************************************************************/
+{
+  LIST Scan1,Scan2;
+
+  for (Scan1=Sort ; !list_Empty(Scan1); Scan1 = list_Cdr(Scan1))
+    for (Scan2=list_Cdr(Scan1) ; !list_Empty(Scan2); Scan2 = list_Cdr(Scan2))
+      if (sort_NodeEqual(list_Car(Scan1),list_Car(Scan2)))
+	return FALSE;
+
+  return TRUE;
+}
+
+BOOL sort_TheorySortEqual(SORTTHEORY Theory, SORT Sort1, SORT Sort2)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+***************************************************************/
+{
+  LIST Scan;
+
+  if (list_Length(Sort1) != list_Length(Sort2))
+    return FALSE;
+
+  sort_TheoryIncrementMark(Theory);
+
+  for (Scan=Sort1; !list_Empty(Scan); Scan=list_Cdr(Scan))
+    sort_PutNodeExtraTrue(Theory,list_Car(Scan));
+  for (Scan=Sort2; !list_Empty(Scan); Scan=list_Cdr(Scan))
+    if (!sort_NodeExtraValue(Theory,list_Car(Scan)))
+      return FALSE;
+
+  return TRUE;
+}
+
+static BOOL sort_TheorySortMember(SORTTHEORY Theory, LIST List, SORT Sort)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+***************************************************************/
+{
+  while (!list_Empty(List)) {
+    if (sort_TheorySortEqual(Theory,list_Car(List),Sort))
+      return TRUE;
+    List = list_Cdr(List);
+  }
+  return FALSE;
+}
+
+
+void sort_DeleteSortPair(SOJU Pair) 
+/**************************************************************
+  INPUT:   
+  RETURNS: Nothing.
+***************************************************************/
+{                                         
+  sort_DeleteOne(sort_PairSort(Pair));   
+  sort_ConditionDelete(sort_PairCondition(Pair));  
+  list_PairFree(Pair);                 
+}
+
+
+
+static void sort_ConditionPrint(CONDITION Cond)
+/**************************************************************
+  INPUT:   
+  RETURNS: Nothing.
+***************************************************************/
+{
+  LIST Scan;
+
+  symbol_Print(sort_ConditionVar(Cond));
+  for (Scan=sort_ConditionConstraint(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    putchar(',');
+    term_PrintPrefix(list_Car(Scan));
+  }
+  for (Scan=sort_ConditionAntecedent(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    putchar(',');
+    term_PrintPrefix(list_Car(Scan));
+  }
+  for (Scan=sort_ConditionSuccedent(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    putchar(',');
+    term_PrintPrefix(list_Car(Scan));
+  }
+  for (Scan=sort_ConditionClauses(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    printf(",%d",clause_Number(list_Car(Scan)));
+  }
+}
+
+static void sort_LinkPrint(SLINK Link)
+/**************************************************************
+  INPUT:   
+  RETURNS: Nothing.
+***************************************************************/
+{
+  LIST Scan;
+
+  fputs("Input: (", stdout);
+  for (Scan=sort_LinkInput(Link);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    symbol_Print(sort_NodeSymbol(list_Car(Scan)));
+    if (!list_Empty(list_Cdr(Scan)))
+      putchar(',');
+  }
+  fputs(") Output: ", stdout);
+  symbol_Print(sort_NodeSymbol(sort_LinkOutput(Link)));
+  fputs("  C: (", stdout);
+  for (Scan=sort_LinkConstraint(Link);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    term_PrintPrefix(list_Car(Scan));
+    if (!list_Empty(list_Cdr(Scan)))
+      putchar(',');
+  }
+  fputs(") A: (", stdout);
+  for (Scan=sort_LinkAntecedent(Link);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    term_PrintPrefix(list_Car(Scan));
+    if (!list_Empty(list_Cdr(Scan)))
+      putchar(',');
+  }
+  fputs(") S: (", stdout);
+  for (Scan=sort_LinkSuccedent(Link);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    term_PrintPrefix(list_Car(Scan));
+    if (!list_Empty(list_Cdr(Scan)))
+      putchar(',');
+  }
+  printf(") Clause: %d Card: %d Fire: %d Var: ", clause_Number(sort_LinkClause(Link)), sort_LinkCard(Link),
+     sort_LinkFire(Link));
+  symbol_Print(sort_LinkVar(Link));
+}
+  
+    
+
+void sort_PairPrint(SOJU Pair)
+/**************************************************************
+  INPUT:   
+  RETURNS: Nothing.
+***************************************************************/
+{
+  sort_Print(sort_PairSort(Pair));
+  fputs(":[", stdout);
+  sort_ConditionPrint(sort_PairCondition(Pair));
+  putchar(']');
+}
+
+
+static NODE sort_NodeCreate(SYMBOL S)
+/**************************************************************
+  INPUT:   A sort symbol.
+  RETURNS: A new initialized sort node for the symbol <S>.
+***************************************************************/
+{
+  NODE Result;
+
+  Result = (NODE)memory_Malloc(sizeof(NODE_NODE));
+
+  sort_PutNodeLinks(Result, list_Nil());
+  sort_PutNodeConditions(Result, list_Nil());
+  sort_PutNodeMark(Result, 0);
+  sort_PutNodeStart(Result, 0);
+  sort_PutNodeExtra(Result, 0);
+  sort_PutNodeSymbol(Result, S);
+
+  return Result;
+}
+
+BOOL sort_NodeIsTop(SORTTHEORY Theory, NODE Node)
+/**************************************************************
+  INPUT:   A sort theory and a node.
+  RETURNS: TRUE if the Node is declared to be equivalent to the
+           top sort.
+***************************************************************/
+{
+  LIST  Scan;
+  SLINK Link;
+
+  for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Link = (SLINK)list_Third(list_Car(Scan));
+    if (list_Empty(sort_LinkInput(Link)) && Node == sort_LinkOutput(Link))
+      return TRUE;
+  }
+  return FALSE; 
+}
+
+
+static SLINK sort_TheoryLinkCreate(SORTTHEORY Theory, CLAUSE Origin,
+				   CLAUSE Clause, LITERAL Lit)
+/**************************************************************
+  INPUT:   A sort theory, a clause its origin and a subsort declaration
+           literal in the clause 
+  RETURNS: A new link in <Theory> origin <Clause> and subsort declaration <Lit>
+***************************************************************/
+{
+  SLINK  Result;
+  SYMBOL Output,Var,Max;
+  int    i;
+  LIST   Input, Antecedent, Succedent, Constraint;
+  TERM   Term;
+
+  Result = (SLINK)memory_Malloc(sizeof(SLINK_NODE));
+
+  Output = term_TopSymbol(clause_LiteralSignedAtom(Lit));
+  Var    = term_TopSymbol(term_FirstArgument(clause_LiteralSignedAtom(Lit)));
+  Input  = Antecedent = Succedent = Constraint = list_Nil();
+  Max    = clause_MaxVar(Clause);
+  term_StartMaxRenaming(Max);
+  Max    = symbol_CreateStandardVariable();
+
+  for (i = clause_FirstConstraintLitIndex(Clause);
+       i <= clause_LastConstraintLitIndex(Clause); i++)
+    if (symbol_Equal(Var,term_TopSymbol(term_FirstArgument(clause_GetLiteralAtom(Clause,i)))))
+      Input = list_Cons(sort_TheoryNode(Theory,term_TopSymbol(clause_GetLiteralAtom(Clause,i))),
+			Input);
+    else {
+      Term = term_Copy(clause_GetLiteralTerm(Clause,i));
+      term_ExchangeVariable(Term,Var,Max);
+      Constraint = list_Cons(Term,Constraint);
+    }
+
+  for (i = clause_FirstAntecedentLitIndex(Clause);
+       i <= clause_LastAntecedentLitIndex(Clause); i++) {
+    Term = term_Copy(clause_GetLiteralTerm(Clause,i));
+    term_ExchangeVariable(Term,Var,Max);
+    Antecedent = list_Cons(Term,Antecedent);
+  }
+
+  for (i = clause_FirstSuccedentLitIndex(Clause);
+       i <= clause_LastSuccedentLitIndex(Clause); i++)
+    if (clause_GetLiteral(Clause,i) != Lit) {
+      Term = term_Copy(clause_GetLiteralTerm(Clause,i));
+      term_ExchangeVariable(Term,Var,Max);
+      Succedent = list_Cons(Term,Succedent);
+    }
+
+
+  sort_PutLinkInput(Result,Input);
+  sort_PutLinkOutput(Result,sort_TheoryNode(Theory,Output));
+  sort_PutLinkVar(Result,Max);
+  sort_PutLinkConstraint(Result,Constraint);
+  sort_PutLinkAntecedent(Result,Antecedent);
+  sort_PutLinkSuccedent(Result,Succedent);
+  sort_PutLinkCard(Result,list_Length(Input));
+  sort_LinkResetFire(Result);
+  sort_PutLinkClause(Result,Origin);
+
+  while (!list_Empty(Input)) {
+    sort_PutNodeLinks(list_Car(Input),list_Cons(Result,sort_NodeLinks(list_Car(Input))));
+    Input = list_Cdr(Input);
+  }
+
+  return Result;
+}
+
+
+void sort_Init(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: None.
+  SUMMARY: Initializes the sort Module.
+  EFFECTS: Initializes global variables, i.e. the BASESORT-Array.
+  CAUTION: MUST BE CALLED BEFORE ANY OTHER sort-FUNCTION.
+***************************************************************/
+{
+  return;
+}
+
+
+void sort_Print(SORT Sort)
+/**************************************************************
+  INPUT:   
+  RETURNS: Nothing.
+***************************************************************/
+{
+  putchar('(');
+  
+  while (!list_Empty(Sort)) {
+    symbol_Print(sort_NodeSymbol(list_Car(Sort)));
+    Sort = list_Cdr(Sort);
+    if (!list_Empty(Sort))
+      putchar(',');
+  }
+  putchar(')');
+}
+
+
+void sort_Free(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: Nothing.
+  SUMMARY: Frees the sort Module.
+***************************************************************/
+{
+  return;
+}
+
+SORTTHEORY sort_TheoryCreate(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: A new sort theory.
+  EFFECT:  A new sort theory is created and initialized.
+***************************************************************/
+{
+  SORTTHEORY Result;
+  int        i;
+  SIGNATURE  Entry;
+  SYMBOL     Symbol;
+
+  Result = (SORTTHEORY)memory_Malloc(sizeof(SORTTHEORY_NODE));
+
+  for (i = 1; i < symbol_ACTINDEX; i++) {
+    Result->basesorttable[i] = (NODE)NULL;
+    Entry = symbol_Signature(i);
+    if (Entry != NULL) {
+      Symbol = Entry->info;
+      if (symbol_IsPredicate(Symbol) && Entry->arity == 1)
+	Result->basesorttable[i] = sort_NodeCreate(Symbol);
+    }
+  }
+  
+  Result->index        = st_IndexCreate();
+  Result->suborigcls   = list_Nil();
+  Result->termorigcls  = list_Nil();
+  Result->mark         = 0;
+
+  return Result;
+}
+
+void sort_TheoryPrint(SORTTHEORY Theory)
+/**************************************************************
+  INPUT:   A sort theory
+  RETURNS: None.
+  EFFECT:  Prints the sort theory to stdout.
+***************************************************************/
+{
+  LIST Scan;
+
+  if (Theory == (SORTTHEORY)NULL) {
+    fputs(" Empty Theory", stdout);
+    return;
+  }
+
+  fputs("\n Subsort Clauses:", stdout);
+  for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    fputs("\n\t\t Clause:", stdout);
+    clause_Print(list_Second(list_Car(Scan)));
+    fputs("\n\t\t Link: ", stdout);
+    sort_LinkPrint(list_Third(list_Car(Scan)));
+  }
+  fputs("\n Term Declaration Clauses:", stdout);
+  for (Scan=sort_TheoryTermorigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    fputs("\n\t\t Clause:", stdout);
+    clause_Print(list_Second(list_Car(Scan)));
+  }
+    
+}
+
+void sort_TheoryDelete(SORTTHEORY Theory)
+/**************************************************************
+  INPUT:   A sort theory
+  RETURNS: None.
+  EFFECT:  The complete sort theory is deleted.
+***************************************************************/
+{
+  if (Theory != (SORTTHEORY)NULL) {
+    int  i;
+    LIST Scan,Tuple;
+    TERM Term, Atom;
+
+    for (Scan=Theory->suborigcls;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+      Tuple = (LIST)list_Car(Scan);
+      sort_LinkDelete(list_Third(Tuple));
+      clause_Delete(list_Second(Tuple));
+      list_Delete(Tuple);
+    }
+    list_Delete(Theory->suborigcls); 
+    for (Scan=Theory->termorigcls;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+      Tuple = (LIST)list_Car(Scan);
+      Term  = (TERM)list_Third(Tuple);
+      Atom  = (TERM)list_Car(term_SupertermList(Term));
+      st_EntryDelete(Theory->index,Term,Term,cont_LeftContext());
+      st_EntryDelete(Theory->index,Atom,Atom,cont_LeftContext());
+      list_Delete(term_SupertermList(Atom));
+      list_Delete(term_SupertermList(Term));
+      term_RplacSupertermList(Term, list_Nil());
+      term_RplacSupertermList(Atom, list_Nil());
+      clause_Delete(list_Second(Tuple));
+      list_Delete(Tuple);
+    }
+    list_Delete(Theory->termorigcls);
+    st_IndexDelete(Theory->index);
+
+    for (i=1;i<symbol_ACTINDEX;i++)
+      if (Theory->basesorttable[i] != (NODE)NULL)
+	sort_NodeDelete(Theory->basesorttable[i]);
+
+    memory_Free(Theory,sizeof(SORTTHEORY_NODE));
+  }
+}
+
+void sort_TheoryInsertClause(SORTTHEORY Theory, CLAUSE Origin, CLAUSE Clause, LITERAL L)
+/**************************************************************
+  INPUT:   A sort theory, two clauses and a declaration of the  second clause.
+           <Origin> is the original clause and <Clause> is a possibly approximated
+	   copy of <Origin>.
+  RETURNS: None.
+  EFFECT:  Inserts <Clause> with declaration <L> into the sort theory.
+***************************************************************/
+{
+  TERM   Term, Atom;
+
+  Term = term_FirstArgument(clause_LiteralSignedAtom(L));
+
+  if (term_IsVariable(Term)) {
+    SLINK Link;
+    Link               = sort_TheoryLinkCreate(Theory,Origin,Clause,L);
+    Theory->suborigcls = list_Cons(list_Cons(Origin,list_Cons(clause_Copy(Clause),list_List(Link))),
+				   Theory->suborigcls);
+  }
+
+  /* Since currently Sort Resolution and Empty Sort require the subsort declaration clauses */
+  /* also subsort clauses are introduced into the sort theory index                         */
+  
+  Atom = clause_LiteralSignedAtom(L);
+  term_RplacSupertermList(Atom, list_List(L)); 
+  term_RplacSupertermList(Term, list_List(Atom));   /* Must be empty before this operation */
+  st_EntryCreate(Theory->index,Term,Term,cont_LeftContext());
+  st_EntryCreate(Theory->index,Atom,Atom,cont_LeftContext());
+  Theory->termorigcls = list_Cons(list_Cons(Origin,list_Cons(Clause,list_List(Term))),
+				  Theory->termorigcls);
+}
+
+void sort_TheoryDeleteClause(SORTTHEORY Theory, CLAUSE Origin)
+/**************************************************************
+  INPUT:   A sort theory and a clause possibly inserted several times in the theory.
+  RETURNS: None.
+  EFFECT:  <Origin> is deleted from the sort theory, but not deleted itself.
+***************************************************************/
+{
+  TERM Term,Atom;
+  LIST Scan,Tuple;   
+
+  for (Scan=Theory->suborigcls;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Tuple = list_Car(Scan);
+    if ((CLAUSE)list_First(Tuple) == Origin) {
+      list_Rplaca(Scan,NULL);
+      sort_LinkDelete(list_Third(Tuple));
+      clause_Delete(list_Second(Tuple));
+      list_Delete(Tuple);
+    }
+  }        
+  Theory->suborigcls = list_PointerDeleteElement(Theory->suborigcls,NULL);
+  for (Scan=Theory->termorigcls;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Tuple = list_Car(Scan);
+    if ((CLAUSE)list_First(Tuple) == Origin) {
+      list_Rplaca(Scan,NULL);
+      Term = (TERM)list_Third(Tuple);
+      Atom = (TERM)list_Car(term_SupertermList(Term));
+      st_EntryDelete(Theory->index,Term,Term,cont_LeftContext());
+      st_EntryDelete(Theory->index,Atom,Atom,cont_LeftContext());
+      list_Delete(term_SupertermList(Atom));
+      list_Delete(term_SupertermList(Term));
+      term_RplacSupertermList(Term, list_Nil());
+      term_RplacSupertermList(Atom, list_Nil());
+      clause_Delete(list_Second(Tuple));
+      list_Delete(Tuple);
+    }
+  }
+  Theory->termorigcls = list_PointerDeleteElement(Theory->termorigcls,NULL);
+}
+
+CONDITION sort_ConditionCreate(SYMBOL Var, LIST Constr, LIST Ante, LIST Succ, LIST Clauses)
+/**************************************************************
+  INPUT:   A variable, a list of constraint literals, antecedent literals, succedent literals
+           and a list of clauses.
+  RETURNS: The condition created from these arguments.
+  MEMORY:  It is assumed that all literals are unshared whereas the clauses are shared.
+***************************************************************/
+{
+  CONDITION Result;
+
+  Result = (CONDITION)memory_Malloc(sizeof(CONDITION_NODE));
+
+  sort_ConditionPutVar(Result, Var);
+  sort_ConditionPutConstraint(Result, Constr);
+  sort_ConditionPutAntecedent(Result, Ante);
+  sort_ConditionPutSuccedent(Result, Succ);
+  sort_ConditionPutClauses(Result, Clauses);
+
+  return Result;
+}
+
+CONDITION sort_ConditionNormalize(CONDITION Cond)
+/**************************************************************
+  INPUT:   A condition.
+  RETURNS: The normalized condition, i.e., the variables for the various
+           literals are normalized starting with the minimal variable.
+  EFFECT:  Destructive.
+***************************************************************/
+{
+  LIST   Scan;
+  SYMBOL Old,New;
+
+  term_StartMinRenaming();
+  for (Scan=sort_ConditionConstraint(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan))
+    term_Rename(list_Car(Scan));
+  for (Scan=sort_ConditionAntecedent(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan))
+    term_Rename(list_Car(Scan));
+  for (Scan=sort_ConditionSuccedent(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan))
+    term_Rename(list_Car(Scan));
+  New = symbol_CreateStandardVariable();
+  Old = term_GetRenamedVarSymbol(sort_ConditionVar(Cond));
+  for (Scan=sort_ConditionConstraint(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan))
+    term_ExchangeVariable(list_Car(Scan),Old,New);
+  for (Scan=sort_ConditionAntecedent(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan))
+    term_ExchangeVariable(list_Car(Scan),Old,New);
+  for (Scan=sort_ConditionSuccedent(Cond);!list_Empty(Scan);Scan=list_Cdr(Scan))
+    term_ExchangeVariable(list_Car(Scan),Old,New);
+
+  sort_ConditionPutVar(Cond,New);
+  
+  return Cond;
+}
+
+CONDITION sort_ConditionCreateNoResidues(LIST Clauses)
+/**************************************************************
+  INPUT:   A list of clauses.
+  RETURNS: The condition created just from the clauses.
+***************************************************************/
+{
+  CONDITION Result;
+
+  Result = (CONDITION)memory_Malloc(sizeof(CONDITION_NODE));
+
+  sort_ConditionPutVar(Result, symbol_FirstVariable());
+  sort_ConditionPutConstraint(Result, list_Nil());
+  sort_ConditionPutAntecedent(Result, list_Nil());
+  sort_ConditionPutSuccedent(Result, list_Nil());
+  sort_ConditionPutClauses(Result, Clauses);
+
+  return Result;
+}
+
+CONDITION sort_ExtendConditionByLink(CONDITION Cond, SLINK Link)
+/**************************************************************
+  INPUT:   A condition and a link.
+  RETURNS: <Cond> extended by the clause, antecedent, constraint and succedent
+           literals of <Link>
+  EFFECT:  <Cond> is destructively extended with <Link>.
+***************************************************************/
+{
+  LIST    Lits,Antecedent,Succedent,Constraint;
+  SYMBOL  Old,New;
+
+  
+  term_StartMaxRenaming(sort_ConditionVar(Cond));
+  Constraint = term_CopyTermList(sort_LinkConstraint(Link));
+  Antecedent = term_CopyTermList(sort_LinkAntecedent(Link));
+  Succedent  = term_CopyTermList(sort_LinkSuccedent(Link));
+  for (Lits=Constraint;!list_Empty(Lits);Lits=list_Cdr(Lits))
+    term_Rename(list_Car(Lits));
+  for (Lits=Antecedent;!list_Empty(Lits);Lits=list_Cdr(Lits))
+    term_Rename(list_Car(Lits));
+  for (Lits=Succedent;!list_Empty(Lits);Lits=list_Cdr(Lits))
+    term_Rename(list_Car(Lits));
+  Old = term_GetRenamedVarSymbol(sort_LinkVar(Link));
+  New = symbol_CreateStandardVariable();
+  for (Lits=Constraint;!list_Empty(Lits);Lits=list_Cdr(Lits))
+    term_ExchangeVariable(list_Car(Lits),Old,New);
+  for (Lits=Antecedent;!list_Empty(Lits);Lits=list_Cdr(Lits))
+    term_ExchangeVariable(list_Car(Lits),Old,New);
+  for (Lits=Succedent;!list_Empty(Lits);Lits=list_Cdr(Lits))
+    term_ExchangeVariable(list_Car(Lits),Old,New);
+  Old = sort_ConditionVar(Cond);
+  for (Lits=sort_ConditionConstraint(Cond);!list_Empty(Lits);Lits=list_Cdr(Lits))
+    term_ExchangeVariable(list_Car(Lits),Old,New);
+  for (Lits=sort_ConditionAntecedent(Cond);!list_Empty(Lits);Lits=list_Cdr(Lits))
+    term_ExchangeVariable(list_Car(Lits),Old,New);
+  for (Lits=sort_ConditionSuccedent(Cond);!list_Empty(Lits);Lits=list_Cdr(Lits))
+    term_ExchangeVariable(list_Car(Lits),Old,New);
+  sort_ConditionPutConstraint(Cond,list_Nconc(sort_ConditionConstraint(Cond),Constraint));
+  sort_ConditionPutAntecedent(Cond,list_Nconc(sort_ConditionAntecedent(Cond),Antecedent));
+  sort_ConditionPutSuccedent(Cond,list_Nconc(sort_ConditionSuccedent(Cond),Succedent));
+  sort_ConditionPutClauses(Cond,list_Cons(sort_LinkClause(Link),sort_ConditionClauses(Cond)));
+  sort_ConditionPutVar(Cond,New);
+  sort_ConditionNormalize(Cond);
+
+  return Cond;
+							
+}
+
+CONDITION sort_ExtendConditionByCondition(CONDITION Cond, CONDITION Update)
+/**************************************************************
+  INPUT:   Two conditions.
+  RETURNS: <Cond> extended by the clauses, antecedent, constraint and succedent
+           literals of <Update>
+  EFFECT:  <Cond> is destructively extended by  <Update>.
+***************************************************************/
+{
+  LIST    Lits,Antecedent,Succedent,Constraint;
+  SYMBOL  Old,New;
+
+  term_StartMaxRenaming(sort_ConditionVar(Cond));
+  Constraint = term_CopyTermList(sort_ConditionConstraint(Update));
+  Antecedent = term_CopyTermList(sort_ConditionAntecedent(Update));
+  Succedent  = term_CopyTermList(sort_ConditionSuccedent(Update));
+  for (Lits=Constraint;!list_Empty(Lits);Lits=list_Cdr(Lits))
+    term_Rename(list_Car(Lits));
+  for (Lits=Antecedent;!list_Empty(Lits);Lits=list_Cdr(Lits))
+    term_Rename(list_Car(Lits));
+  for (Lits=Succedent;!list_Empty(Lits);Lits=list_Cdr(Lits))
+    term_Rename(list_Car(Lits));
+  Old = term_GetRenamedVarSymbol(sort_ConditionVar(Update));
+  New = symbol_CreateStandardVariable();
+  for (Lits=Constraint; !list_Empty(Lits); Lits=list_Cdr(Lits))
+    term_ExchangeVariable(list_Car(Lits),Old,New);
+  for (Lits=Antecedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+    term_ExchangeVariable(list_Car(Lits),Old,New);
+  for (Lits=Succedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+    term_ExchangeVariable(list_Car(Lits),Old,New);
+  Old = sort_ConditionVar(Cond);
+  for (Lits=sort_ConditionConstraint(Cond);!list_Empty(Lits);Lits=list_Cdr(Lits))
+    term_ExchangeVariable(list_Car(Lits),Old,New);
+  for (Lits=sort_ConditionAntecedent(Cond);!list_Empty(Lits);Lits=list_Cdr(Lits))
+    term_ExchangeVariable(list_Car(Lits),Old,New);
+  for (Lits=sort_ConditionSuccedent(Cond);!list_Empty(Lits);Lits=list_Cdr(Lits))
+    term_ExchangeVariable(list_Car(Lits),Old,New);
+  sort_ConditionPutConstraint(Cond,list_Nconc(sort_ConditionConstraint(Cond),Constraint));
+  sort_ConditionPutAntecedent(Cond,list_Nconc(sort_ConditionAntecedent(Cond),Antecedent));
+  sort_ConditionPutSuccedent(Cond,list_Nconc(sort_ConditionSuccedent(Cond),Succedent));
+  sort_ConditionPutClauses(Cond,list_Nconc(list_Copy(sort_ConditionClauses(Update)),
+					   sort_ConditionClauses(Cond)));
+  sort_ConditionPutVar(Cond,New);
+  sort_ConditionNormalize(Cond);
+
+  return Cond;
+}
+
+LIST sort_ExtendConditions(LIST Conditions, SLINK Link)
+/**************************************************************
+  INPUT:   A list of conditions and a link.
+  RETURNS: A new list of conditions augmented by the conditions in <Link>.
+***************************************************************/
+{
+  LIST      Result,Scan,Antecedent,Succedent,Constraint;
+  CONDITION Cond;
+
+  Result = list_Nil();
+
+  for (Scan=Conditions;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Cond       = (CONDITION)list_Car(Scan);
+    Constraint = term_CopyTermList(sort_ConditionConstraint(Cond));
+    Antecedent = term_CopyTermList(sort_ConditionAntecedent(Cond));
+    Succedent  = term_CopyTermList(sort_ConditionSuccedent(Cond));
+    if (sort_LinkNoResidues(Link))
+      Result = list_Cons(sort_ConditionCreate(sort_ConditionVar(Cond),Constraint,Antecedent,
+					      Succedent,list_Cons(sort_LinkClause(Link),
+							list_Copy(sort_ConditionClauses(Cond)))),
+			 Result);
+    else {
+      SYMBOL New,Old;
+      LIST   NewAntecedent,NewSuccedent,NewConstraint,Lits;
+      term_StartMaxRenaming(sort_ConditionVar(Cond));
+      NewConstraint = term_CopyTermList(sort_LinkConstraint(Link));
+      NewAntecedent = term_CopyTermList(sort_LinkAntecedent(Link));
+      NewSuccedent  = term_CopyTermList(sort_LinkSuccedent(Link));
+      for (Lits=NewConstraint; !list_Empty(Lits); Lits=list_Cdr(Lits))
+	term_Rename(list_Car(Lits));
+      for (Lits=NewAntecedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+	term_Rename(list_Car(Lits));
+      for (Lits=NewSuccedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+	term_Rename(list_Car(Lits));
+      Old = term_GetRenamedVarSymbol(sort_LinkVar(Link));
+      New = symbol_CreateStandardVariable();
+      for (Lits=NewConstraint; !list_Empty(Lits); Lits=list_Cdr(Lits))
+	term_ExchangeVariable(list_Car(Lits),Old,New);
+      for (Lits=NewAntecedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+	term_ExchangeVariable(list_Car(Lits),Old,New);
+      for (Lits=NewSuccedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+	term_ExchangeVariable(list_Car(Lits),Old,New);
+      Old = sort_ConditionVar(Cond);
+      for (Lits=Constraint; !list_Empty(Lits); Lits=list_Cdr(Lits))
+	term_ExchangeVariable(list_Car(Lits),Old,New);
+      for (Lits=Antecedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+	term_ExchangeVariable(list_Car(Lits),Old,New);
+      for (Lits=Succedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+	term_ExchangeVariable(list_Car(Lits),Old,New);
+      Result = list_Cons(sort_ConditionNormalize(sort_ConditionCreate(New,list_Nconc(Constraint,NewConstraint),
+					      list_Nconc(Antecedent,NewAntecedent),
+					      list_Nconc(Succedent,NewSuccedent),
+					      list_Cons(sort_LinkClause(Link),
+							list_Copy(sort_ConditionClauses(Cond))))),
+			 Result);      
+    }
+  }
+  return Result;
+}
+
+CONDITION sort_ConditionsUnion(LIST Conditions)
+/**************************************************************
+  INPUT:   A list of conditions.
+  RETURNS: A new condition that is the union of all input conditions.
+***************************************************************/
+{
+  LIST      Scan,Antecedent,Succedent,Constraint;
+  CONDITION Cond;
+  SYMBOL    Act,New,Old;
+  LIST      NewAntecedent,NewSuccedent,NewConstraint,NewClauses,Lits;
+
+  if (list_Empty(Conditions))
+    return sort_ConditionCreate(symbol_FirstVariable(),list_Nil(),list_Nil(),list_Nil(),
+				list_Nil());
+  else {
+    Cond          = (CONDITION)list_Car(Conditions);
+    Conditions    = list_Cdr(Conditions);
+    Act           = sort_ConditionVar(Cond);
+    NewConstraint = term_CopyTermList(sort_ConditionConstraint(Cond));
+    NewAntecedent = term_CopyTermList(sort_ConditionAntecedent(Cond));
+    NewSuccedent  = term_CopyTermList(sort_ConditionSuccedent(Cond));
+    NewClauses    = list_Copy(sort_ConditionClauses(Cond));
+  }
+
+  for (Scan=Conditions;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Cond       = (CONDITION)list_Car(Scan);
+    if (!sort_ConditionNoResidues(Cond)) {
+      Constraint = term_CopyTermList(sort_ConditionConstraint(Cond));
+      Antecedent = term_CopyTermList(sort_ConditionAntecedent(Cond));
+      Succedent  = term_CopyTermList(sort_ConditionSuccedent(Cond));
+
+      term_StartMaxRenaming(Act);
+      for (Lits=Constraint; !list_Empty(Lits); Lits=list_Cdr(Lits))
+	term_Rename(list_Car(Lits));
+      for (Lits=Antecedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+	term_Rename(list_Car(Lits));
+      for (Lits=Succedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+	term_Rename(list_Car(Lits));
+      Old = term_GetRenamedVarSymbol(sort_ConditionVar(Cond));
+      New = symbol_CreateStandardVariable();
+      for (Lits=Constraint; !list_Empty(Lits); Lits=list_Cdr(Lits))
+	term_ExchangeVariable(list_Car(Lits),Old,New);
+      for (Lits=Antecedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+	term_ExchangeVariable(list_Car(Lits),Old,New);
+      for (Lits=Succedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+	term_ExchangeVariable(list_Car(Lits),Old,New);
+      for (Lits=NewConstraint; !list_Empty(Lits); Lits=list_Cdr(Lits))
+	term_ExchangeVariable(list_Car(Lits),Act,New);
+      for (Lits=NewAntecedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+	term_ExchangeVariable(list_Car(Lits),Act,New);
+      for (Lits=NewSuccedent; !list_Empty(Lits); Lits=list_Cdr(Lits))
+	term_ExchangeVariable(list_Car(Lits),Act,New);
+      Act = New;
+      NewConstraint = list_Nconc(Constraint,NewConstraint);
+      NewAntecedent = list_Nconc(Antecedent,NewAntecedent);
+      NewSuccedent  = list_Nconc(Succedent,NewSuccedent);
+    }
+    NewClauses    = list_Nconc(list_Copy(sort_ConditionClauses(Cond)),NewClauses);
+  }
+
+  return sort_ConditionNormalize(sort_ConditionCreate(Act,NewConstraint,NewAntecedent,NewSuccedent,NewClauses));
+}
+
+void sort_ConditionDelete(CONDITION C)
+/**************************************************************
+  INPUT:   A condition.
+  RETURNS: Nothing.
+  MEMORY:  The condition and all literals and lists are deleted.
+***************************************************************/
+{
+  if (C!= (CONDITION)NULL) {
+    term_DeleteTermList(sort_ConditionConstraint(C));
+    term_DeleteTermList(sort_ConditionAntecedent(C));
+    term_DeleteTermList(sort_ConditionSuccedent(C));
+    list_Delete(sort_ConditionClauses(C));
+  
+    sort_ConditionFree(C); 
+  }
+}
+
+
+CONDITION sort_ConditionCopy(CONDITION C)
+/**************************************************************
+  INPUT:   A condition.
+  RETURNS: A copy of the condition.
+***************************************************************/
+{
+  return sort_ConditionCreate(sort_ConditionVar(C),
+			      term_CopyTermList(sort_ConditionConstraint(C)),
+			      term_CopyTermList(sort_ConditionAntecedent(C)),
+			      term_CopyTermList(sort_ConditionSuccedent(C)),
+			      list_Copy(sort_ConditionClauses(C)));
+}
+
+
+    
+BOOL sort_IsBaseSortSymbol(SYMBOL Symbol)
+/*********************************************************
+  INPUT:   A Symbol.
+  RETURNS: The boolean value TRUE, if 'Symbol' is a
+           basesortsymbol, FALSE else.
+*******************************************************/
+{
+#ifdef CHECK
+  if (!symbol_IsSymbol(Symbol)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sort_IsBaseSymbol :");
+    misc_ErrorReport(" Illegal input. Input not a symbol.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  return(symbol_IsPredicate(Symbol) && symbol_Arity(Symbol) == 1);
+}
+
+
+SORT sort_TheorySortOfSymbol(SORTTHEORY Theory, SYMBOL Symbol)
+/*********************************************************
+  INPUT:   A sort theory and a base sort symbol.
+  RETURNS: The Basesort of 'Symbol'.
+*******************************************************/
+{
+#ifdef CHECK
+  if (!sort_IsBaseSortSymbol(Symbol)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sort_TheorySortOfSymbol :");
+    misc_ErrorReport(" Illegal input. Input not a symbol.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  return (list_List(sort_TheoryNode(Theory, Symbol)));
+}
+
+
+static void sort_EvalSubsortNoResidues(SORTTHEORY Theory, LIST Nodes)
+/*********************************************************
+  INPUT:   A sort theory and a list of nodes from this theory.
+  RETURNS: None.
+  EFFECT:  Starting from the nodes in <Nodes> the subsort
+           graph is exploited as long as links fire and
+	   new nodes become true. Only links without residues
+	   are considered.
+*******************************************************/
+{
+  NODE  Node,Head;
+  LIST  Scan,Help,Clauses;
+  SLINK Link;
+
+  while (!list_Empty(Nodes)) {
+    Node  = (NODE)list_Car(Nodes);
+    Scan  = Nodes;
+    Nodes = list_Cdr(Nodes);
+    list_Free(Scan);
+
+    for (Scan = sort_NodeLinks(Node);
+	 !list_Empty(Scan);
+	 Scan = list_Cdr(Scan)) {
+      Link = (SLINK)list_Car(Scan);
+      if (sort_LinkNoResidues(Link) && sort_LinkDecrementFire(Link) == 0) {
+	Head = sort_LinkOutput(Link);
+	if (!sort_NodeValue(Theory, Head)) {
+	  Clauses = list_List(sort_LinkClause(Link));
+	  for (Help=sort_LinkInput(Link);!list_Empty(Help);Help=list_Cdr(Help))
+	    if (!list_Empty(sort_NodeConditions(list_Car(Help))))
+	      Clauses = 
+		list_Nconc(list_Copy(sort_ConditionClauses(
+		       list_Car(sort_NodeConditions(list_Car(Help))))),Clauses);
+	  sort_DeleteConditionList(sort_NodeConditions(Head));
+	  sort_PutNodeConditions(Head,list_List(sort_ConditionCreateNoResidues(Clauses)));
+	  sort_PutNodeTrue(Theory, Head);
+	  Nodes = list_Cons(Head,Nodes);
+	}
+      }
+    }
+  }
+}
+
+
+static BOOL sort_TestSubsortSpecial(SORTTHEORY Theory, LIST Nodes, LIST Goal)
+/*********************************************************
+  INPUT:   A sort theory and a list of nodes from this theory and
+           a list of goal nodes.
+  RETURNS: TRUE if we can walk from at least one node of <Nodes> over
+           a previously evaluated sort structure.
+*******************************************************/
+{
+  NODE  Node,Head;
+  LIST  Scan;
+  SLINK Link;
+
+  while (!list_Empty(Nodes)) {
+    Node  = (NODE)list_NCar(&Nodes);
+    if (list_PointerMember(Goal,Node)) {
+      list_Delete(Nodes);
+      return TRUE;
+    }
+    for (Scan = sort_NodeLinks(Node);!list_Empty(Scan);Scan = list_Cdr(Scan)) {
+      Link = (SLINK)list_Car(Scan);
+      if (sort_LinkFire(Link) == 0) {
+	Head = sort_LinkOutput(Link);
+	Nodes = list_Cons(Head,Nodes);
+      }
+    }
+  }
+  return FALSE;
+}
+
+static void sort_EvalSubsortSpecial(SORTTHEORY Theory, LIST Nodes)
+/*********************************************************
+  INPUT:   A sort theory and a list of nodes from this theory.
+  RETURNS: None.
+  EFFECT:  Starting from the nodes in <Nodes> the subsort
+           graph is exploited as long as links fire and
+	   new nodes become true. Only links without residues
+	   are considered.
+*******************************************************/
+{
+  NODE  Node,Head;
+  LIST  Scan;
+  SLINK Link;
+
+  while (!list_Empty(Nodes)) {
+    Node  = (NODE)list_NCar(&Nodes);
+    for (Scan = sort_NodeLinks(Node);!list_Empty(Scan);Scan = list_Cdr(Scan)) {
+      Link = (SLINK)list_Car(Scan);
+      if (sort_LinkDecrementFire(Link) == 0) {
+	Head = sort_LinkOutput(Link);
+	if (!sort_NodeValue(Theory, Head)) {
+	  sort_PutNodeTrue(Theory, Head);
+	  Nodes = list_Cons(Head,Nodes);
+	}
+      }
+    }
+  }
+}
+
+static void sort_EvalSubsort(SORTTHEORY Theory, LIST Nodes)
+/*********************************************************
+  INPUT:   A sort theory and a list of nodes from this theory.
+  RETURNS: None.
+  EFFECT:  Starting from the nodes in <Nodes> the subsort
+           graph is exploited as long as links fire and
+	   new nodes become true.
+	   Only ONE condition for each node becoming
+	   valid is established.
+*******************************************************/
+{
+  NODE      Node,Head;
+  LIST      Scan,Help;
+  SLINK     Link;
+  CONDITION Cond;
+
+  while (!list_Empty(Nodes)) {
+    Node  = (NODE)list_Car(Nodes);
+    Scan  = Nodes;
+    Nodes = list_Cdr(Nodes);
+    list_Free(Scan);
+
+    for (Scan = sort_NodeLinks(Node);
+	 !list_Empty(Scan);
+	 Scan = list_Cdr(Scan)) {
+      Link = (SLINK)list_Car(Scan);
+      if (sort_LinkDecrementFire(Link) == 0) {
+	Head = sort_LinkOutput(Link);
+	if (!sort_NodeValue(Theory, Head)) {
+	  Cond = sort_ConditionCreate(symbol_FirstVariable(),list_Nil(),list_Nil(),list_Nil(),list_Nil());
+	  for (Help=sort_LinkInput(Link);!list_Empty(Help);Help=list_Cdr(Help))
+	    if (!list_Empty(sort_NodeConditions(list_Car(Help))))
+	      Cond = sort_ExtendConditionByCondition(Cond,list_Car(sort_NodeConditions(list_Car(Help))));
+	  sort_ExtendConditionByLink(Cond,Link);
+	  sort_DeleteConditionList(sort_NodeConditions(Head));
+	  sort_PutNodeConditions(Head,list_List(Cond));
+	  sort_PutNodeTrue(Theory, Head);
+	  Nodes = list_Cons(Head,Nodes);
+	}
+      }
+    }
+  }
+}
+
+
+CONDITION sort_TheoryIsSubsortOfNoResidues(SORTTHEORY Theory, SORT Sort1, SORT Sort2)
+/*********************************************************
+  INPUT:   A sort theory and two sorts.
+  RETURNS: A condition if <Sort1> is a subsort of <Sort2> and NULL otherwise.
+*******************************************************/
+{
+  LIST   Scan,Clauses;
+  SLINK  Link;
+  NODE   Node;
+  SORT   Top;
+
+#ifdef CHECK
+  if (!sort_IsSort(Sort1) || !sort_IsSort(Sort2)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sort_TheoryIsSubsortOfNoResidues :");
+    misc_ErrorReport(" Illegal sort input.\n");
+    misc_FinishErrorReport();
+  }
+#endif 
+
+  sort_TheoryIncrementMark(Theory);
+
+  /*fputs("\n Subsort Test: ", stdout);
+    sort_Print(Sort1);
+    putchar(' ');
+    sort_Print(Sort2);*/
+
+  for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Link = (SLINK)list_Third(list_Car(Scan));
+    sort_LinkResetFire(Link);
+  }
+
+  for (Scan=Sort1;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Node = (NODE)list_Car(Scan);
+    sort_DeleteConditionList(sort_NodeConditions(Node));
+    sort_PutNodeConditions(Node,list_List(sort_ConditionCreate(symbol_FirstVariable(),
+	       list_Nil(),list_Nil(),list_Nil(),list_Nil())));
+    sort_PutNodeTrue(Theory, Node);
+  }
+
+  Top = sort_TopSort();
+  for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Link = (SLINK)list_Third(list_Car(Scan));
+    if (list_Empty(sort_LinkInput(Link)) && sort_LinkNoResidues(Link)) {
+      Node  = sort_LinkOutput(Link);
+      Top = sort_AddBaseNode(Top,Node);
+      sort_DeleteConditionList(sort_NodeConditions(Node));
+      sort_PutNodeConditions(Node,list_List(sort_ConditionCreateNoResidues(list_List(sort_LinkClause(Link)))));
+      sort_PutNodeTrue(Theory,Node);
+    }
+  }
+
+  sort_EvalSubsortNoResidues(Theory,sort_Intersect(Top,sort_Copy(Sort1)));
+  Top = sort_TopSort();
+
+  Clauses = list_Nil();
+
+  for (Scan=Sort2;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Node = (NODE)list_Car(Scan);
+    if (!sort_NodeValue(Theory,Node)) {
+      /*puts(" FALSE");*/
+      list_Delete(Clauses);
+      return NULL;
+    }
+    else
+      if (!list_Empty(sort_NodeConditions(Node)))
+	Clauses = list_Nconc(list_Copy(sort_ConditionClauses(list_Car(sort_NodeConditions(Node)))),
+			     Clauses);
+  }
+  /*printf(" TRUE %lu\n",(unsigned long)Clauses);*/
+  return sort_ConditionCreateNoResidues(Clauses);
+}
+
+BOOL sort_TheoryIsSubsortOf(SORTTHEORY Theory, SORT Sort1, SORT Sort2)
+/*********************************************************
+  INPUT:   A sort theory and two sorts.
+  RETURNS: TRUE if <Sort1> is a subsort of <Sort2> and NULL otherwise.
+*******************************************************/
+{
+  LIST   Scan;
+  SLINK  Link;
+  NODE   Node;
+
+  sort_TheoryIncrementMark(Theory);
+
+  /*fputs("\n Subsort Test: ", stdout);
+    sort_Print(Sort1);
+    putchar(' ');
+    sort_Print(Sort2);*/
+
+  for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Link = (SLINK)list_Third(list_Car(Scan));
+    sort_LinkResetFire(Link);
+  }
+
+  for (Scan=Sort1;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Node = (NODE)list_Car(Scan);
+    sort_PutNodeTrue(Theory, Node);
+  }
+
+  sort_EvalSubsortSpecial(Theory,sort_Copy(Sort1));
+
+  for (Scan=Sort2;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Node = (NODE)list_Car(Scan);
+    if (!sort_NodeValue(Theory,Node)) 
+      return FALSE;
+  }
+
+  return TRUE;
+    
+}
+
+BOOL sort_TheoryIsSubsortOfExtra(SORTTHEORY Theory, SORT Extra, SORT Sort1, SORT Sort2)
+/*********************************************************
+  INPUT:   A sort theory and three sorts.
+  RETURNS: TRUE if <Sort1> is a subsort of <Sort2> and <Extra> is
+                   useful for that purpose
+*******************************************************/
+{
+  LIST   Scan;
+  SLINK  Link;
+  NODE   Node;
+
+  sort_TheoryIncrementMark(Theory);
+
+  /*fputs("\n Subsort Test: ", stdout);
+    sort_Print(Sort1);
+    putchar(' ');
+    sort_Print(Sort2);*/
+
+  for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Link = (SLINK)list_Third(list_Car(Scan));
+    sort_LinkResetFire(Link);
+  }
+
+  for (Scan=Sort1;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Node = (NODE)list_Car(Scan);
+    sort_PutNodeTrue(Theory, Node);
+  }
+
+  sort_EvalSubsortSpecial(Theory,sort_Copy(Sort1));
+
+  for (Scan=Sort2;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Node = (NODE)list_Car(Scan);
+    if (!sort_NodeValue(Theory,Node)) 
+      return FALSE;
+  }
+
+  return sort_TestSubsortSpecial(Theory,sort_Copy(Extra),Sort2);
+    
+}
+
+LIST sort_TheoryComputeAllSubsortHits(SORTTHEORY Theory, SORT Sort1, SORT Sort2)
+/*********************************************************
+  INPUT:   A sort theory and two sorts.
+  RETURNS: All possible sorts that are subsets of <Sort1> that are subsorts
+           of <Sort2> together with all conditions.
+*******************************************************/
+{
+  LIST   Scan,Result,Search,Scan2,Visited;
+  SLINK  Link;
+  NODE   Node;
+  SOJU   Cand;
+  BOOL   Valid,ValidStart;
+  NAT    StartMark;
+
+  sort_TheoryIncrementMark(Theory);
+  StartMark = sort_TheoryMark(Theory);
+
+  /*fputs("\n Exhaustive Subsort Test: ", stdout);
+    sort_Print(Sort1);
+    putchar(' ');
+    sort_Print(Sort2);*/
+
+  for (Scan=sort_TheorySuborigcls(Theory);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Link = (SLINK)list_Third(list_Car(Scan));
+    sort_LinkResetFire(Link);
+  }
+
+  for (Scan=Sort1;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Node = (NODE)list_Car(Scan);
+    sort_DeleteConditionList(sort_NodeConditions(Node));
+    sort_PutNodeConditions(Node,list_List(sort_ConditionCreate(symbol_FirstVariable(),
+	       list_Nil(),list_Nil(),list_Nil(),list_Nil())));
+    sort_PutNodeTrue(Theory, Node);
+    sort_PutNodeStartTrue(Theory,Node);
+  }
+
+  sort_EvalSubsort(Theory,sort_Copy(Sort1));
+
+  for (Scan=Sort2;!list_Empty(Scan);Scan=list_Cdr(Scan)) {/* Subsort condition must hold */
+    Node = (NODE)list_Car(Scan);
+    if (!sort_NodeValue(Theory,Node))
+      return list_Nil();
+  }
+  
+  Result  = list_Nil();
+  Search  = list_List(sort_PairCreate(sort_Copy(Sort2),sort_ConditionCreateNoResidues(list_Nil())));
+  Visited = list_Nil();
+  fputs("\n\n Starting Soju Search:", stdout);
+
+  while (!list_Empty(Search)) {
+    Cand   = (SOJU)list_Car(Search);
+    Scan   = Search;
+    Search = list_Cdr(Search);
+    list_Free(Scan);
+    putchar('\n');
+    sort_PairPrint(Cand);
+
+    if (!sort_TheorySortMember(Theory,Visited,sort_PairSort(Cand))) {
+      Visited = list_Cons(sort_Copy(sort_PairSort(Cand)),Visited);
+      ValidStart = TRUE;
+      Valid      = TRUE;
+      for (Scan=sort_PairSort(Cand);!list_Empty(Scan) && (ValidStart || Valid);Scan=list_Cdr(Scan)) {
+	Node = (NODE)list_Car(Scan);
+	if (sort_NodeMark(Node) != StartMark) {
+	  Valid      = FALSE;
+	  ValidStart = FALSE;
+	}
+	else
+	  if (sort_NodeStart(Node) != StartMark)
+	    ValidStart = FALSE;
+      }
+      if (Valid) {
+	if (ValidStart) 
+	  Result = list_Cons(sort_PairCopy(Cand),Result);
+
+	for (Scan=sort_PairSort(Cand);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+	  Node = (NODE)list_Car(Scan);
+	  for (Scan2=sort_TheorySuborigcls(Theory);!list_Empty(Scan2);Scan2=list_Cdr(Scan2)) {
+	    Link = (SLINK)list_Third(list_Car(Scan2));
+	    if (sort_LinkOutput(Link) == Node && !list_Empty(sort_LinkInput(Link)))
+	      Search = list_Cons(sort_PairCreate(list_PointerDeleteDuplicates(sort_Intersect(sort_DeleteBaseNode(sort_Copy(sort_PairSort(Cand)),Node),sort_Copy(sort_LinkInput(Link)))),
+						 sort_ExtendConditionByLink(sort_ConditionCopy(sort_PairCondition(Cand)),Link)),
+				 Search);
+	  }
+	}
+      }
+      sort_PairDelete(Cand);
+    }
+  }
+  list_DeleteWithElement(Visited,(void (*)(POINTER)) sort_Delete);
+      
+  return Result;    
+}
+
+static SORT sort_VarSort(SORTTHEORY Theory, SYMBOL Var, CLAUSE Clause, int i)
+/*********************************************************
+  INPUT:   A variable symbol, a clause and a literal index in the clause.
+  RETURNS: The sort of  <Var> with respect to the sort constraint 
+           literals (possibly in the antecedent)
+           in <Clause> except literal <i> that is not considered.
+  MEMORY:  Both Sorts are destroyed.
+*******************************************************/
+{
+  SORT Result;
+  int j;
+  TERM Atom;
+  
+  Result = sort_TopSort();
+  
+  for (j=clause_FirstConstraintLitIndex(Clause);j<=clause_LastAntecedentLitIndex(Clause);j++) 
+    if (j != i) {
+      Atom = clause_LiteralAtom(clause_GetLiteral(Clause,j));
+      if (symbol_IsBaseSort(term_TopSymbol(Atom)) &&
+	  term_TopSymbol(term_FirstArgument(Atom)) == Var)
+	Result = sort_Intersect(Result,sort_TheorySortOfSymbol(Theory,term_TopSymbol(Atom)));
+    }
+  
+  return Result;
+}
+
+
+static BOOL sort_MatchNoResidues(SORTTHEORY Theory, TERM Term1, TERM Term2, CLAUSE Clause, LIST* Clauses)
+/*********************************************************
+  INPUT:   A sort theory, two terms, a clause and list of clauses
+           as an additional return parameter.
+  RETURNS: TRUE iff there exists a well-sorted matcher from <Term1> to <Term2>
+           The sorts of variables in <Term1> is determined by the sort constraint in <Clause>
+	   The sorts of subterms of <Term2> are assumed to be already computed and stored.
+*******************************************************/
+{
+  int       l;
+  SUBST     subst,scan;
+  SORT      varsort;
+  LIST      NewClauses;
+  SOJU      Pair;
+  CONDITION Cond;
+  
+  l          = clause_Length(Clause);
+  NewClauses = list_Nil();
+
+  cont_StartBinding();
+  unify_Match(cont_LeftContext(),Term1,Term2);
+  subst = subst_ExtractMatcher();
+  cont_BackTrack();
+  
+  /*putchar('\n'); term_Print(Term1);fputs("->",stdout);
+    term_Print(Term2);putchar(':');subst_Print(subst);
+    putchar('\n');*/
+  for (scan=subst;!subst_Empty(scan);scan=subst_Next(scan)) {
+    varsort = sort_VarSort(Theory,subst_Dom(scan),Clause,l);
+    Pair    = hash_Get(subst_Cod(scan));
+    if ((Cond = sort_TheoryIsSubsortOfNoResidues(Theory,sort_PairSort(Pair),varsort)) == NULL) {
+      sort_DeleteOne(varsort);
+      list_Delete(NewClauses);
+      subst_Free(subst);
+      return FALSE;
+    } else {
+      NewClauses = list_Nconc(NewClauses,
+			      list_Copy(sort_ConditionClauses(sort_PairCondition(Pair))));
+      NewClauses = list_Nconc(NewClauses,sort_ConditionClauses(Cond));
+      sort_ConditionPutClauses(Cond,list_Nil());
+      sort_ConditionDelete(Cond);
+    }
+    
+    sort_DeleteOne(varsort);
+  }
+  
+  subst_Free(subst);
+  *Clauses = list_Nconc(NewClauses,*Clauses);
+  return TRUE;
+}
+
+
+static SOJU sort_ComputeSortInternNoResidues(SORTTHEORY Theory, TERM Term,
+					     CLAUSE Clause, int i,
+					     FLAGSTORE Flags,
+					     PRECEDENCE Precedence)
+/*********************************************************
+  INPUT:   A Term, a sort theory representing a set of
+           clauses, a clause wrt that variable sorts are
+	   computed, where the literal <i> is discarded,
+	   a flag store and a precedence.
+	   The sorts of 'Term's args have to be known.
+  RETURNS: The sort of 'Term' wrt. the sort theory of the
+           clause set. Be careful, the Sort-entries of
+	   'Term' and its subterms are changed.
+*******************************************************/
+{
+  SORT Sort;
+  LIST HelpList, Scan, Clauses;
+  TERM QueryTerm;
+  
+  Sort    = sort_TopSort();
+  Clauses = list_Nil();
+  
+  if (term_IsVariable(Term))
+    Sort = sort_VarSort(Theory,term_TopSymbol(Term),Clause,i);
+  else {
+    HelpList = st_GetGen(cont_LeftContext(), sort_TheoryIndex(Theory), Term);
+    for (Scan=HelpList;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+      SYMBOL  Top;
+      LITERAL ActLit;
+      TERM    Atom;
+      CLAUSE  ActClause;
+      
+      QueryTerm = (TERM)list_First(Scan);
+
+      if (!term_IsVariable(QueryTerm)) { /* Currently also subort declarations are in the index ...*/ 
+	Atom      = (TERM)list_First(term_SupertermList(QueryTerm));
+	Top       = term_TopSymbol(Atom);
+	ActLit    = (LITERAL)list_First(term_SupertermList(Atom));
+	ActClause = clause_LiteralOwningClause(ActLit);
+	if (clause_IsSortTheoryClause(ActClause, Flags, Precedence) &&
+	    sort_MatchNoResidues(Theory,QueryTerm,Term, ActClause,&Clauses) &&
+	    !sort_ContainsSymbol(Sort,Top)) {
+	  Sort        = sort_Intersect(Sort,sort_TheorySortOfSymbol(Theory,Top));
+	  Clauses     = list_Cons(ActClause,Clauses);
+	}
+      }
+    }
+    list_Delete(HelpList);
+  }
+  return (sort_PairCreate(Sort,sort_ConditionCreateNoResidues(Clauses)));
+}
+
+
+SOJU sort_ComputeSortNoResidues(SORTTHEORY Theory, TERM Term, CLAUSE Clause,
+				int i, FLAGSTORE Flags, PRECEDENCE Precedence) 
+/*********************************************************
+  INPUT:   A Term and an Index representing a set of
+           clauses, a clause to access 
+	   variable-sort-information where the literal <i>
+	   is discarded, a flag store and a precedence.
+  RETURNS: The sort of 'Term' wrt. the sort theory of the
+           clause set and the clauses used for this 
+	   computation.
+	   Be careful, the Sort-entries of
+	   'Term' and its subterms are changed, if they
+	   already existed.
+*******************************************************/
+{
+  int  SubtermStack;
+  SOJU SortPair;
+
+  SortPair     = (SOJU)NULL;
+  SubtermStack = stack_Bottom();
+  sharing_PushOnStack(Term);
+
+
+  while (!stack_Empty(SubtermStack)){
+    Term = stack_PopResult();
+    
+    if (!(SortPair = (SOJU)hash_Get(Term))) {
+      SortPair = sort_ComputeSortInternNoResidues(Theory,Term,Clause,i,
+						  Flags, Precedence);
+      /*fputs("\n Computed:",stdout);term_Print(Term);
+	putchar(':');sort_PairPrint(SortPair);putchar('\n');*/
+      hash_Put(Term,SortPair);
+    }
+  }
+
+  SortPair = sort_PairCopy(SortPair);
+  hash_ResetWithValue((void (*)(POINTER)) sort_DeleteSortPair);
+
+  return(SortPair);
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *	      Creating and Analyzing Sort Theories          * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+static BOOL sort_SortTheoryIsTrivial(SORTTHEORY Theory, LIST Clauses)
+/*********************************************************
+  INPUT:   A sort theory and a list of clauses that generated the theory.
+  RETURNS: TRUE iff all considered base sorts are top.
+*******************************************************/
+{
+  LIST      Sorts;
+  CLAUSE    Clause;
+  int       i,n;
+  CONDITION Cond;
+
+  Sorts = list_Nil();
+
+  /* fputs("\n\nAnalyzing Theory:", stdout); */
+
+  while (!list_Empty(Clauses)) {
+    Clause  = (CLAUSE)list_Car(Clauses);
+    n       = clause_Length(Clause);
+    Clauses = list_Cdr(Clauses);
+
+    /* fputs("\n\t", stdout);clause_Print(Clause); */
+
+    for (i=clause_FirstConstraintLitIndex(Clause); i<n; i++)
+      Sorts = list_Cons((POINTER)term_TopSymbol(clause_LiteralAtom(
+                clause_GetLiteral(Clause,i))), Sorts);
+
+    Sorts = list_PointerDeleteDuplicates(Sorts);
+  }
+
+  Clauses = Sorts;
+  while (!list_Empty(Clauses)) {
+    list_Rplaca(Clauses,sort_TheorySortOfSymbol(Theory,(SYMBOL)list_Car(Clauses)));
+    Clauses = list_Cdr(Clauses);
+  }
+
+  n       = list_Length(Sorts);
+  i       = 0;
+  Clauses = Sorts;
+
+  /* printf("\n\t  There are %d different sorts.",n); */
+
+  while (!list_Empty(Clauses)) {
+    if ((Cond = sort_TheoryIsSubsortOfNoResidues(Theory,sort_TopSort(),list_Car(Clauses)))) {
+      sort_ConditionDelete(Cond);
+      i++;
+    }
+    sort_DeleteOne(list_Car(Clauses));
+    Clauses = list_Cdr(Clauses);
+  }
+
+  list_Delete(Sorts);
+
+  return (i == n);   /* All sorts are trivial */
+}
+
+
+static LIST sort_ApproxPseudoLinear(LIST Constraint, TERM Head, SYMBOL Var)
+/**************************************************************
+  INPUT:   A list of constraint literals, the head literal term
+           and a variable maximal for all variables.
+  RETURNS: The new list of constraint literals. 
+  EFFECT:  The succedent literal is made pseudo-linear.
+           The function is DESTRUCTIVE.
+***************************************************************/
+{
+  TERM   Atom;
+  LIST   RenVars,Scan1,Scan2,Lits;
+  SYMBOL OldVar, NewVar;
+
+  RenVars = term_RenamePseudoLinear(Head,Var);
+  Lits    = list_Nil();
+
+  for (Scan1=RenVars;!list_Empty(Scan1);Scan1=list_Cdr(Scan1)) {
+    OldVar = (SYMBOL)list_PairFirst(list_Car(Scan1));
+    NewVar = (SYMBOL)list_PairSecond(list_Car(Scan1));
+    list_PairFree(list_Car(Scan1));
+    for (Scan2=Constraint;!list_Empty(Scan2);Scan2=list_Cdr(Scan2)) {
+      Atom = (TERM)list_Car(Constraint);
+      if (symbol_Equal(term_TopSymbol(term_FirstArgument(Atom)),OldVar))
+	Lits = list_Cons(term_Create(term_TopSymbol(Atom),
+		 list_List(term_Create(NewVar,list_Nil()))), Lits);
+    }
+  }
+  list_Delete(RenVars);
+
+  Lits = list_Nconc(Constraint,Lits);
+
+  return Lits;
+}
+
+
+static LIST sort_ApproxHornClauses(CLAUSE Clause, FLAGSTORE Flags,
+				   PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause to make special horn clauses from, a flag
+           store and a precedence.
+  RETURNS: The list of clauses according to the rule
+           ClauseDeletion.
+  MEMORY:  Allocates memory for the clauses and the list.
+***************************************************************/
+{
+  LIST    Result, NewConstraint,NewSuccedent;
+  CLAUSE  NewClause;
+  LITERAL LitK;
+  int     i,length,j,lc,pli;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sort_ApproxHornClauses :");
+    misc_ErrorReport(" Illegal input. Input not a clause.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Result = list_Nil();
+
+  if (clause_HasOnlyVarsInConstraint(Clause, Flags, Precedence) &&
+      clause_HasSortInSuccedent(Clause, Flags, Precedence)) {
+    length = clause_Length(Clause);
+    
+    for (i = clause_FirstSuccedentLitIndex(Clause); i < length; i++) {
+      LitK = clause_GetLiteral(Clause, i);
+      
+      if (symbol_Arity(term_TopSymbol(clause_LiteralSignedAtom(LitK))) == 1) {
+	pli           = i;
+	NewSuccedent  = list_List(term_Copy(clause_LiteralSignedAtom(LitK)));
+	NewConstraint = list_Nil();
+	lc            = clause_LastConstraintLitIndex(Clause);
+
+	for (j = clause_FirstLitIndex(); j <= lc; j++)
+	  if (clause_LitsHaveCommonVar(LitK, clause_GetLiteral(Clause, j)))
+	    NewConstraint = list_Cons(term_Copy(clause_LiteralAtom(
+                              clause_GetLiteral(Clause, j))), NewConstraint);
+
+	if (!list_Empty(NewConstraint))  
+	    NewConstraint = sort_ApproxPseudoLinear(NewConstraint,
+						    list_Car(NewSuccedent),
+						    clause_MaxVar(Clause));
+	
+	NewClause = clause_Create(NewConstraint, list_Nil(), NewSuccedent, 
+				  Flags, Precedence);
+	clause_SetSplitLevel(NewClause, 0);
+	clause_SetFlag(NewClause,WORKEDOFF);
+	clause_SetFromClauseDeletion(NewClause);
+	clause_SetParentClauses(NewClause, list_List((POINTER)clause_Number(Clause)));
+	clause_AddParentLiteral(NewClause, pli);
+
+	list_Delete(NewConstraint); 
+	list_Delete(NewSuccedent); 
+	Result    = list_Cons(NewClause, Result);
+      }
+    }
+  }
+  return(Result);
+}
+
+LIST sort_ApproxMaxDeclClauses(CLAUSE Clause, FLAGSTORE Flags,
+			       PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A declaration clause to make special horn clauses
+           from, a flag store and a precedence.
+  RETURNS: The list of Horn clauses that are pseudo-linear declaration
+           clauses generated from maximal declarations in <Clause>
+  MEMORY:  Allocates memory for the clauses and the list.
+***************************************************************/
+{
+  LIST    Result, NewConstraint,NewSuccedent;
+  CLAUSE  NewClause;
+  LITERAL LitK;
+  int     i,length,j,lc,pli;
+
+#ifdef CHECK
+  if (!clause_IsClause(Clause, Flags, Precedence) || 
+      !clause_IsDeclarationClause(Clause)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In sort_ApproxMaxDeclClauses :");
+    misc_ErrorReport(" Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Result = list_Nil();
+  length = clause_Length(Clause);
+    
+  for (i = clause_FirstSuccedentLitIndex(Clause); i < length; i++) {
+    LitK = clause_GetLiteral(Clause, i);
+      
+    if (clause_LiteralIsMaximal(LitK) &&
+	symbol_IsBaseSort(term_TopSymbol(clause_LiteralSignedAtom(LitK)))) {
+      pli           = i;
+      NewSuccedent  = list_List(term_Copy(clause_LiteralSignedAtom(LitK)));
+      NewConstraint = list_Nil();
+      lc            = clause_LastConstraintLitIndex(Clause);
+
+      for (j = clause_FirstLitIndex(); j <= lc; j++)
+	if (clause_LitsHaveCommonVar(LitK, clause_GetLiteral(Clause, j)))
+	  NewConstraint = list_Cons(term_Copy(clause_LiteralAtom(clause_GetLiteral(Clause, j))), 
+				    NewConstraint);
+
+      if (!list_Empty(NewConstraint))  
+	NewConstraint = sort_ApproxPseudoLinear(NewConstraint,
+						list_Car(NewSuccedent),
+						clause_MaxVar(Clause));
+	
+      NewClause = clause_Create(NewConstraint, list_Nil(), NewSuccedent,
+				Flags, Precedence);
+      clause_SetSplitLevel(NewClause, 0);
+      clause_SetFlag(NewClause,WORKEDOFF);
+      clause_SetFromClauseDeletion(NewClause);
+      clause_SetParentClauses(NewClause, list_List(Clause));  /* The clause itself is added! */
+      clause_AddParentLiteral(NewClause, pli);
+
+      list_Delete(NewConstraint); 
+      list_Delete(NewSuccedent); 
+      Result    = list_Cons(NewClause, Result);
+    }
+  }
+  return(Result);
+}
+
+
+static LIST sort_ApproxClauses(LIST Clauses, FLAGSTORE Flags,
+			       PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A list of top level clauses, a flag store and a
+           precedence.
+  RETURNS: A list of approximated clauses from <Clauses> which must
+           be used for sort deletion.
+  EFFECT:  None.
+***************************************************************/
+{
+  LIST   Result,ApproxClauses;
+  CLAUSE ActClause;
+
+  Result = list_Nil();
+
+  while (!list_Empty(Clauses)) {
+    ActClause     = (CLAUSE)list_Car(Clauses);
+    ApproxClauses = sort_ApproxHornClauses(ActClause, Flags, Precedence);
+    Result        = list_Nconc(ApproxClauses,Result);
+    Clauses       = list_Cdr(Clauses);
+  }
+
+  return Result;
+}
+
+LIST sort_EliminateSubsumedClauses(LIST Clauses)
+/*********************************************************
+  INPUT:   A list of clauses.
+  RETURNS: <Clauses> without subsumed clauses.
+*******************************************************/
+{
+  LIST RedundantClauses,Iter,Scan;
+  BOOL Kept;
+
+  RedundantClauses  = list_Nil();
+  for (Scan = Clauses; !list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Kept = TRUE;
+    for (Iter = Clauses;!list_Empty(Iter) && Kept; Iter = list_Cdr(Iter))
+      if (list_Car(Iter) != list_Car(Scan) &&
+	  !list_PointerMember(RedundantClauses,list_Car(Iter)) &&
+	  subs_Subsumes(list_Car(Iter),list_Car(Scan),subs_NoException(),subs_NoException())) {
+	Kept             = FALSE;
+	RedundantClauses = list_Cons(list_Car(Scan),RedundantClauses);
+      }
+  }
+  Clauses = list_NPointerDifference(Clauses,RedundantClauses);
+  clause_DeleteClauseList(RedundantClauses);
+  return Clauses;
+}
+
+
+SORTTHEORY sort_ApproxStaticSortTheory(LIST Clauses, FLAGSTORE Flags,
+				       PRECEDENCE Precedence)
+/*********************************************************
+  INPUT:   A list of clauses, a flag store and a
+           precedence.
+  RETURNS: NULL if the approximated sort theory is trivial,
+           the approximated sort theory otherwise.
+*******************************************************/
+{
+  LIST       Scan,ApproxClauses;
+  CLAUSE     Clause;
+  SORTTHEORY Result;
+
+  Result        = sort_TheoryCreate();
+  ApproxClauses = sort_ApproxClauses(Clauses, Flags, Precedence);
+  ApproxClauses = sort_EliminateSubsumedClauses(ApproxClauses);
+
+  /*fputs("\n\n Approx Sort Theory:", stdout);
+    for (Scan = ApproxClauses; !list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    fputs("\n\t",stdout); clause_Print(list_Car(Scan));
+    }*/
+  
+  for (Scan = ApproxClauses; !list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    Clause = (CLAUSE)list_Car(Scan);
+    sort_TheoryInsertClause(Result,Clause,Clause,
+			    clause_GetLiteral(Clause,clause_FirstSuccedentLitIndex(Clause)));
+  }
+
+  if (sort_SortTheoryIsTrivial(Result,ApproxClauses)) {
+    sort_TheoryDelete(Result);
+    Result = (SORTTHEORY)NULL;
+  }
+    
+  
+  if (flag_GetFlagValue(Flags, flag_DOCSST)) {
+    fputs("\n\n Approx Sort Theory:", stdout);
+    if (Result) {
+      puts("\n");
+      sort_TheoryPrint(Result);
+    }
+    else
+      fputs(" trivial.", stdout);
+  }    
+  list_Delete(ApproxClauses);
+
+  return Result;
+}
+
+
+SORTTHEORY sort_ApproxDynamicSortTheory(LIST Clauses)
+/*********************************************************
+  INPUT:   A list of clauses.
+  RETURNS: The approximated dynamic sort theory for <Clauses>
+           Only maximal declarations are considered.
+*******************************************************/
+{
+  return (SORTTHEORY)NULL;
+}
+
+STR sort_AnalyzeSortStructure(LIST Clauses, FLAGSTORE Flags,
+			      PRECEDENCE Precedence)
+/*********************************************************
+  INPUT:   A list of clauses, a flag store and a
+           precedence.
+  RETURNS: SORTEQMANY if all positive equations are many
+           sorted.
+           SORTEQDEC  if all positive equations are sort
+	   decreasing.
+	   SORTEQNONE otherwise.
+	   For the check, the static sort theory is
+	   considered.
+*******************************************************/
+{
+  SORTTHEORY Theory;
+  LIST       Scan;
+  CLAUSE     Clause,Copy;
+  int        i,l;
+  TERM       Atom,Left,Right;
+  SOJU       SojuLeft,SojuRight;
+  CONDITION  Cond;
+  BOOL       ManySorted, Decreasing;
+
+  Theory       = sort_TheoryCreate();
+  ManySorted   = TRUE;
+  Decreasing   = TRUE;
+
+  for (Scan=Clauses;!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    /* Extract static sort theory */
+    Clause = (CLAUSE)list_Car(Scan);
+    if (clause_IsPotentialSortTheoryClause(Clause, Flags, Precedence)) {
+      Copy = clause_Copy(Clause);
+      symbol_AddProperty(term_TopSymbol(clause_GetLiteralTerm(Copy, 
+			 clause_FirstSuccedentLitIndex(Copy))),
+			 DECLSORT);
+      list_Delete(clause_ParentClauses(Copy));
+      clause_SetParentClauses(Copy,list_Nil());
+      list_Delete(clause_ParentLiterals(Copy));
+      clause_SetParentLiterals(Copy,list_Nil());
+      clause_SetNumber(Copy,clause_Number(Clause));
+      clause_SetSortConstraint(Copy,FALSE, Flags, Precedence);
+      sort_TheoryInsertClause(Theory,Clause,Copy,
+			      clause_GetLiteral(Copy,clause_FirstSuccedentLitIndex(Copy)));
+    }
+  }
+
+  /*putchar('\n');
+    sort_TheoryPrint(Theory);
+    putchar('\n');*/
+
+  for (Scan=Clauses;!list_Empty(Scan) && Decreasing;Scan=list_Cdr(Scan)) {
+    Clause = (CLAUSE)list_Car(Scan);
+    l      = clause_Length(Clause);
+    for (i=clause_FirstSuccedentLitIndex(Clause);i<l && Decreasing;i++) {
+      Atom = clause_GetLiteralTerm(Clause,i);
+      if (fol_IsEquality(Atom)) {
+	Left      = term_FirstArgument(Atom);
+	Right     = term_SecondArgument(Atom);
+	SojuLeft  = sort_ComputeSortNoResidues(Theory, Left, Clause, i, 
+					       Flags, Precedence);
+	SojuRight = sort_ComputeSortNoResidues(Theory, Right,Clause, i,
+					       Flags, Precedence);
+	if (sort_IsTopSort(sort_PairSort(SojuRight)) || sort_IsTopSort(sort_PairSort(SojuLeft))) {
+	  /*fputs("\nNon decreasing equation ",stdout); term_PrintPrefix(Atom);
+	    fputs(" in clause: ",stdout);clause_Print(Clause);putchar('\n');*/
+	  ManySorted = FALSE;
+	  Decreasing = FALSE;
+	}
+	else {
+	  if (!sort_Eq(sort_PairSort(SojuRight), sort_PairSort(SojuLeft))) {
+	    ManySorted = FALSE;
+	    Cond = sort_TheoryIsSubsortOfNoResidues(Theory, sort_PairSort(SojuRight), 
+						    sort_PairSort(SojuLeft));
+	    if (Cond && !clause_LiteralIsOrientedEquality(clause_GetLiteral(Clause,i))) {
+	      sort_ConditionDelete(Cond);
+	      Cond = sort_TheoryIsSubsortOfNoResidues(Theory, sort_PairSort(SojuLeft),
+						      sort_PairSort(SojuRight));
+	    }
+	    if (Cond)
+	      sort_ConditionDelete(Cond);
+	    else {
+	      /*fputs("\nNon decreasing equation ",stdout); term_PrintPrefix(Atom);
+		fputs(" in clause: ",stdout);clause_Print(Clause);putchar('\n');*/
+	      Decreasing = FALSE;
+	    }
+	  }
+	}
+	sort_PairDelete(SojuLeft);
+	sort_PairDelete(SojuRight);
+      }
+    }
+  }    
+  sort_TheoryDelete(Theory);
+  if (ManySorted)
+    return SORTEQMANY;
+  if (Decreasing)
+    return SORTEQDECR;
+
+  return SORTEQNONE;
+}
+
diff --git a/test/spass/sort.h b/test/spass/sort.h
new file mode 100644
index 0000000000000000000000000000000000000000..83bc5472dd1b093c0b58cde2d4cfb3a73ea3d14b
--- /dev/null
+++ b/test/spass/sort.h
@@ -0,0 +1,598 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                  SORTED REASONING                      * */
+/* *                                                        * */
+/* *  $Module:   SORT                                       * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _SORT_
+#define _SORT_
+
+#include "clause.h"
+#include "unify.h"
+#include "hash.h"
+#include "subsumption.h"
+
+
+/**************************************************************/
+/* Data Structures and Constants                              */
+/**************************************************************/
+
+/* Objects of type SORT are used to store the sort information */
+/* for terms. SORT is a list of NODE's                        */
+
+typedef LIST SORT;
+/* List of sort nodes */
+
+typedef LIST SOJU;
+/* Pair: First Component Sort, Second Component Condition */
+
+typedef enum {SORTEQNONE=1, SORTEQDECR=2, SORTEQMANY=3} STR;
+/* The overall result of an sort theory analysis with respect to equations */
+
+typedef struct CONDITION_HELP {
+  SYMBOL var;
+  LIST   constraint;
+  LIST   antecedent;
+  LIST   succedent;
+  LIST   clauses;
+} CONDITION_NODE,*CONDITION;
+
+/* This data structure collects the conditions from conditioned subsort clauses */
+/* The constraint, antecedent, succedent lists contain lists of atoms used to  */
+/* derive the subsort relationship that come from clauses.                     */
+
+
+typedef struct NODE_HELP {
+  LIST   links;
+  NAT    mark;
+  NAT    start;
+  NAT    extra;
+  LIST   conditions;
+  SYMBOL symbol;
+} NODE_NODE,*NODE;
+
+/* This is a node from the subsort graph with outgoing links the represented   */
+/* sort symbol and a mark indicating whether the node is already visited,i.e,  */
+/* it is TRUE. Whereas start indicates whether the node was put true right     */
+/* from the beginning. Conditions contains a list of conditions needed to set  */
+/* the node true.                                                              */
+
+typedef struct SLINK_HELP {
+  LIST   input;                    
+  NODE   output;                   
+  int    card;                     
+  int    fire;
+  LIST   constraint;
+  LIST   antecedent;
+  LIST   succedent;
+  SYMBOL var;
+  CLAUSE clause;                   
+} SLINK_NODE,*SLINK;
+
+/* This is a link in the subsort graph, with a list of input nodes that have   */
+/* to become true in order to fire the link and set the output node TRUE       */
+/* constraint, antecedent, succedent literals are the extra literals of        */
+/* <clause> and <var> is the subsort variable. It is always assumed that the   */
+/* subsort variable is the maximal variable with respect to the constraint,    */
+/* antecedent and succedent literals.                                          */
+
+typedef struct SORTTHEORY_HELP {
+  st_INDEX index;                                 
+  NODE     basesorttable[symbol__MAXSIGNATURE];   
+  LIST     suborigcls;
+  LIST     termorigcls;
+  NAT      mark;        
+} SORTTHEORY_NODE,*SORTTHEORY;
+
+/* The index contains the term declarations mapped to their possibly           */
+/* approximated term declarations of inserted clauses. The subsort declarations*/
+/* are handled by a specific graph initiated over the base sorts. There is     */
+/* one node in the graph for every base sort (basesorttable) and links         */
+/* correspond to subsort declaration clauses                                   */
+/* The mark is used in the subsort graph to detect already visited nodes.      */
+/* The lists suborigcls and termorigcls map original clauses to sort theory    */
+/* clauses to links/terms respectively. They contain triples of this kind      */
+
+
+
+/**************************************************************/
+/* Extern                                                     */
+/**************************************************************/
+
+void      sort_ConditionDelete(CONDITION);
+CONDITION sort_ConditionCopy(CONDITION);
+
+
+/**************************************************************/
+/* Macros                                                     */
+/**************************************************************/
+
+static __inline__ SORT sort_TopSort(void)
+{
+  return list_Nil();
+}
+
+static __inline__ BOOL sort_IsTopSort(SORT S)
+{
+  return list_Empty(S);
+}
+
+static __inline__ SORT sort_Copy(SORT S)
+{
+  return list_Copy(S);
+}
+
+static __inline__ void sort_DeleteOne(SORT S)
+{
+  list_Delete(S);
+}
+
+static __inline__ SORT sort_Intersect(SORT S1, SORT S2)
+{
+  return list_Nconc(S1, S2);
+}
+
+static __inline__ SORT sort_DeleteBaseNode(SORT S, NODE N)
+{
+  return list_PointerDeleteElement(S,N);
+}
+
+static __inline__ SORT sort_AddBaseNode(SORT S, NODE N)
+{
+  return list_Cons(N,S);
+}
+
+static __inline__ void sort_NodeFree(NODE N)
+{
+  memory_Free(N,sizeof(NODE_NODE));
+}
+
+static __inline__ BOOL sort_NodeEqual(NODE N1, NODE N2)
+{
+  return (N1 == N2);
+}
+
+static __inline__ void sort_DeleteConditionList(LIST List)
+{
+  list_DeleteWithElement(List, (void (*)(POINTER)) sort_ConditionDelete);
+}
+
+static __inline__ void sort_NodeDelete(NODE N)
+{
+  list_Delete(N->links);
+  N->links = list_Nil();
+  sort_DeleteConditionList(N->conditions);
+  N->conditions = list_Nil();
+  sort_NodeFree(N);
+}
+
+static __inline__ LIST sort_NodeLinks(NODE N)
+{
+  return N->links;
+}
+
+static __inline__ BOOL sort_NodeValue(SORTTHEORY S, NODE N)
+{
+  return (N->mark == S->mark);
+}
+
+static __inline__ BOOL sort_NodeExtraValue(SORTTHEORY S, NODE N)
+{
+  return (N->extra == S->mark);
+}
+
+static __inline__ BOOL sort_NodeStartValue(SORTTHEORY S, NODE N)
+{
+  return (N->start == S->mark);
+}
+
+static __inline__ NAT sort_NodeMark(NODE N)
+{
+  return N->mark;
+}
+
+static __inline__ NAT sort_NodeStart(NODE N)
+{
+  return N->start;
+}
+
+static __inline__ SYMBOL sort_NodeSymbol(NODE N)
+{
+  return N->symbol;
+}
+
+static __inline__ LIST sort_NodeConditions(NODE N)
+{
+  return N->conditions;
+}
+
+static __inline__ void sort_PutNodeMark(NODE N, NAT M)
+{
+  N->mark = M;
+}
+
+static __inline__ void sort_PutNodeExtra(NODE N, NAT M)
+{
+  N->extra = M;
+}
+
+static __inline__ void sort_PutNodeStart(NODE N, NAT S)
+{
+  N->start = S;
+}
+
+static __inline__ void sort_PutNodeSymbol(NODE N, SYMBOL S)
+{
+  N->symbol = S;
+}
+
+static __inline__ void sort_PutNodeLinks(NODE N, LIST C)
+{
+  N->links = C;
+}
+
+static __inline__ void sort_PutNodeConditions(NODE N, LIST C)
+{
+  N->conditions = C;
+}
+
+static __inline__ void sort_PutNodeTrue(SORTTHEORY S, NODE N)
+{
+  N->mark = S->mark;
+}
+
+static __inline__ void sort_PutNodeExtraTrue(SORTTHEORY S, NODE N)
+{
+  N->extra = S->mark;
+}
+
+static __inline__ void sort_PutNodeStartTrue(SORTTHEORY S, NODE N)
+{
+  N->start = S->mark;
+}
+
+static __inline__ LIST sort_LinkInput(SLINK S)
+{
+  return S->input;
+}
+
+static __inline__ NODE sort_LinkOutput(SLINK S)
+{
+  return S->output;
+}
+
+static __inline__ int sort_LinkFire(SLINK S)
+{
+  return S->fire;
+}
+
+static __inline__ int sort_LinkVar(SLINK S)
+{
+  return S->var;
+}
+
+static __inline__ LIST sort_LinkConstraint(SLINK S)
+{
+  return S->constraint;
+}
+
+static __inline__ LIST sort_LinkAntecedent(SLINK S)
+{
+  return S->antecedent;
+}
+
+static __inline__ LIST sort_LinkSuccedent(SLINK S)
+{
+  return S->succedent;
+}
+
+static __inline__ CLAUSE sort_LinkClause(SLINK S)
+{
+  return S->clause;
+}
+
+static __inline__ int sort_LinkCard(SLINK S)
+{
+  return S->card;
+}
+
+static __inline__ void sort_PutLinkInput(SLINK S, LIST T)
+{
+  S->input = T;
+}
+
+static __inline__ void sort_PutLinkVar(SLINK S, SYMBOL V)
+{
+  S->var = V;
+}
+
+static __inline__ void sort_PutLinkConstraint(SLINK S, LIST T)
+{
+  S->constraint = T;
+}
+
+static __inline__ void sort_PutLinkAntecedent(SLINK S, LIST T)
+{
+  S->antecedent = T;
+}
+
+static __inline__ void sort_PutLinkSuccedent(SLINK S, LIST T)
+{
+  S->succedent = T;
+}
+
+static __inline__ void sort_PutLinkOutput(SLINK S,NODE H)
+{
+  S->output = H;
+}
+
+static __inline__ void sort_PutLinkClause(SLINK S, CLAUSE C)
+{
+  S->clause = C;
+}
+
+static __inline__ void sort_PutLinkCard(SLINK S,int L)
+{
+  S->card = L;
+}
+
+static __inline__ void sort_LinkResetFire(SLINK S) {
+  S->fire = S->card;
+}
+
+static __inline__ int sort_LinkDecrementFire(SLINK S)
+{
+  --(S->fire);
+  return S->fire;
+}
+
+static __inline__ void sort_LinkFree(SLINK S)
+{
+  memory_Free(S,sizeof(SLINK_NODE));
+}
+
+static __inline__ void sort_LinkDelete(SLINK S)
+{
+  LIST Scan;
+  for (Scan=sort_LinkInput(S); !list_Empty(Scan); Scan=list_Cdr(Scan))
+    sort_PutNodeLinks(list_Car(Scan),list_PointerDeleteElement(sort_NodeLinks(list_Car(Scan)),S));
+  list_Delete(sort_LinkInput(S));
+  term_DeleteTermList(sort_LinkConstraint(S));
+  term_DeleteTermList(sort_LinkAntecedent(S));
+  term_DeleteTermList(sort_LinkSuccedent(S));
+  sort_LinkFree(S);
+}
+
+static __inline__ SYMBOL sort_ConditionVar(CONDITION C)
+{
+  return C->var;
+}
+
+static __inline__ LIST sort_ConditionConstraint(CONDITION C)
+{
+  return C->constraint;
+}
+
+static __inline__ LIST sort_ConditionAntecedent(CONDITION C)
+{
+  return C->antecedent;
+}
+
+static __inline__ LIST sort_ConditionSuccedent(CONDITION C)
+{
+  return C->succedent;
+}
+
+static __inline__ LIST sort_ConditionClauses(CONDITION C)
+{
+  return C->clauses;
+}
+
+static __inline__ void sort_ConditionPutVar(CONDITION C, SYMBOL Var)
+{
+   C->var = Var;
+}
+
+static __inline__ void sort_ConditionPutConstraint(CONDITION C, LIST Constr)
+{
+   C->constraint = Constr;
+}
+
+static __inline__ void sort_ConditionPutAntecedent(CONDITION C, LIST Ante)
+{
+   C->antecedent = Ante;
+}
+
+static __inline__ void sort_ConditionPutSuccedent(CONDITION C, LIST Succ)
+{
+   C->succedent = Succ;
+}
+
+static __inline__ void sort_ConditionPutClauses(CONDITION C, LIST Clauses)
+{
+   C->clauses = Clauses;
+}
+
+static __inline__ void sort_ConditionFree(CONDITION C)
+{
+  memory_Free(C, sizeof(CONDITION_NODE));
+}
+
+static __inline__ BOOL sort_ConditionNoResidues(CONDITION C)
+{
+  return (list_Empty(sort_ConditionConstraint(C)) &&
+	  list_Empty(sort_ConditionAntecedent(C)) &&
+	  list_Empty(sort_ConditionSuccedent(C)));
+}
+
+
+
+static __inline__ BOOL sort_LinkNoResidues(SLINK S)
+{
+  return (list_Empty(sort_LinkConstraint(S)) &&
+	  list_Empty(sort_LinkAntecedent(S)) &&
+	  list_Empty(sort_LinkSuccedent(S)));
+}
+
+static __inline__ BOOL sort_HasEqualSort(SORT S1, SORT S2)
+{
+  return S1 == S2;
+}
+
+
+static __inline__ POINTER sort_PairSort(LIST Pair)
+{
+  return list_PairFirst(Pair);
+}
+
+static __inline__ POINTER sort_PairCondition(LIST Pair)
+{
+  return list_PairSecond(Pair);
+}
+
+static __inline__ LIST sort_PairCreate(SORT S , CONDITION Just)
+{
+  return list_PairCreate((POINTER)S, Just);
+}
+
+static __inline__ void sort_PairFree(LIST Pair)
+{
+  list_PairFree(Pair);
+}
+
+static __inline__ void sort_PairDelete(LIST Pair)
+{
+  sort_DeleteOne(sort_PairSort(Pair));
+  sort_ConditionDelete(sort_PairCondition(Pair));
+  list_PairFree(Pair);
+}
+
+static __inline__ LIST sort_PairCopy(LIST Pair)
+{
+  return sort_PairCreate(sort_Copy(sort_PairSort(Pair)),
+			 sort_ConditionCopy(sort_PairCondition(Pair)));
+}
+
+static __inline__ NODE sort_TheoryNode(SORTTHEORY Theory, SYMBOL S)
+{
+  return Theory->basesorttable[symbol_Index(S)];
+}
+
+static __inline__ NAT sort_TheoryMark(SORTTHEORY Theory)
+{
+  return Theory->mark;
+}
+
+static __inline__ LIST sort_TheorySuborigcls(SORTTHEORY Theory)
+{
+  return Theory->suborigcls;
+}
+
+static __inline__ LIST sort_TheoryTermorigcls(SORTTHEORY Theory)
+{
+  return Theory->termorigcls;
+}
+
+static __inline__ void sort_TheoryIncrementMark(SORTTHEORY Theory)
+{
+  if (Theory->mark == NAT_MAX) {
+    int  i;   
+    NODE Node;
+    for (i = 0; i < symbol__MAXSIGNATURE; i++) {
+      Node = Theory->basesorttable[i];
+      Node->mark  = 0;
+      Node->extra = 0;
+      Node->start = 0;
+    }
+    Theory->mark = 0;      
+  } 
+  ++(Theory->mark);
+}
+
+static __inline__ st_INDEX sort_TheoryIndex(SORTTHEORY Theory)
+{
+  return Theory->index;
+}
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+void sort_Init(void);
+void sort_Free(void);
+
+void sort_Delete(SORT);
+BOOL sort_Eq(SORT, SORT);
+void sort_DeleteSortPair(SOJU);
+
+void sort_Print(SORT);
+void sort_PairPrint(SOJU);
+
+LIST sort_GetSymbolsFromSort(SORT);
+BOOL sort_ContainsSymbol(SORT, SYMBOL);
+BOOL sort_IsSort(SORT);
+
+
+SORTTHEORY sort_ApproxStaticSortTheory(LIST, FLAGSTORE, PRECEDENCE);
+SORTTHEORY sort_ApproxDynamicSortTheory(LIST);
+
+
+SORTTHEORY sort_TheoryCreate(void);
+void       sort_TheoryDelete(SORTTHEORY);
+void       sort_TheoryPrint(SORTTHEORY);
+void       sort_TheoryInsertClause(SORTTHEORY, CLAUSE, CLAUSE, LITERAL);
+void       sort_TheoryDeleteClause(SORTTHEORY, CLAUSE);
+SORT       sort_TheorySortOfSymbol(SORTTHEORY, SYMBOL);
+BOOL       sort_TheorySortEqual(SORTTHEORY,SORT,SORT);
+CONDITION  sort_TheoryIsSubsortOfNoResidues(SORTTHEORY, SORT, SORT);
+BOOL       sort_TheoryIsSubsortOf(SORTTHEORY, SORT, SORT);
+BOOL       sort_TheoryIsSubsortOfExtra(SORTTHEORY , SORT , SORT , SORT);
+LIST       sort_TheoryComputeAllSubsortHits(SORTTHEORY, SORT, SORT);
+SOJU       sort_ComputeSortNoResidues(SORTTHEORY,TERM, CLAUSE, int, FLAGSTORE, PRECEDENCE);
+LIST       sort_ApproxMaxDeclClauses(CLAUSE, FLAGSTORE, PRECEDENCE);
+STR        sort_AnalyzeSortStructure(LIST, FLAGSTORE, PRECEDENCE);
+
+
+#endif
diff --git a/test/spass/st.c b/test/spass/st.c
new file mode 100644
index 0000000000000000000000000000000000000000..5f591ef22ba55982d6672514bf1abe03a937bc87
--- /dev/null
+++ b/test/spass/st.c
@@ -0,0 +1,1691 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                    ST INDEXING                         * */
+/* *                                                        * */
+/* *  $Module:   ST                                         * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "st.h"
+
+
+/**************************************************************/
+/* Local Variables                                            */
+/**************************************************************/
+
+static st_RETRIEVAL_TYPE st_CURRENT_RETRIEVAL;
+static st_WHERE_TYPE     st_WHICH_CONTEXTS;
+static CONTEXT           st_INDEX_CONTEXT;
+static st_MINMAX         st_EXIST_MINMAX;
+
+/**************************************************************/
+/* Global Variables                                           */
+/**************************************************************/
+
+ST_STACK st_STACK;
+int      st_STACKPOINTER;
+int      st_STACKSAVE;
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  CREATION OF INDEX                                     * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+st_INDEX st_IndexCreate(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: A pointer to a new St-Index.
+  SUMMARY: Creates a new St-index.
+***************************************************************/
+{
+  st_INDEX StIndex;
+
+  StIndex           = st_Get();
+  StIndex->subnodes = list_Nil();
+  StIndex->entries  = list_Nil();
+  StIndex->subst    = subst_Nil();
+  st_SetMax(StIndex, 0);
+  st_SetMin(StIndex, 0);
+
+  return StIndex;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  CREATION OF INDEX NODES                               * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+static st_INDEX st_NodeAddLeaf(SUBST Subst, st_MINMAX MinMax, POINTER Pointer)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{ 
+  st_INDEX NewLeaf;
+
+  NewLeaf           = st_Get();
+  NewLeaf->subnodes = list_Nil();
+  NewLeaf->entries  = list_List(Pointer);
+  NewLeaf->subst    = Subst;
+  st_SetMax(NewLeaf, MinMax);
+  st_SetMin(NewLeaf, MinMax);
+
+  return NewLeaf;
+}
+
+
+static void st_NodeAddInner(st_INDEX StIndex, SUBST SubstOld, SUBST SubstNew,
+			    SUBST ComGen, st_MINMAX MinMax, POINTER Pointer)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  st_INDEX OldIndexNode;
+
+  OldIndexNode           = st_Get();
+  OldIndexNode->subst    = SubstOld;
+  OldIndexNode->entries  = StIndex->entries;
+  OldIndexNode->subnodes = StIndex->subnodes;
+  st_SetMax(OldIndexNode, st_Max(StIndex));
+  st_SetMin(OldIndexNode, st_Min(StIndex));
+
+  subst_Delete(StIndex->subst);
+
+  StIndex->subst         = ComGen;
+  StIndex->entries       = list_Nil();
+  StIndex->subnodes      = list_Cons(st_NodeAddLeaf(SubstNew, MinMax, Pointer),
+				     list_List(OldIndexNode));
+
+  if (st_Max(StIndex) < MinMax)
+    st_SetMax(StIndex, MinMax);
+  else if (st_Min(StIndex) > MinMax)
+    st_SetMin(StIndex, MinMax);
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  MERGING OF INDEX NODES                                * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+static void st_NodeMergeWithSon(st_INDEX StIndex)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  st_INDEX SubNode;
+
+  SubNode = (st_INDEX)list_Car(StIndex->subnodes);
+
+  list_Delete(StIndex->subnodes);
+
+  StIndex->subst    = subst_Merge(SubNode->subst, StIndex->subst);
+  StIndex->entries  = SubNode->entries;
+  StIndex->subnodes = SubNode->subnodes;
+  st_SetMax(StIndex, st_Max(SubNode));
+  st_SetMin(StIndex, st_Min(SubNode));
+
+  subst_Delete(SubNode->subst);
+
+  st_Free(SubNode);
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  VARIABLE HANDLING FOR TERMS AND SUBSTS.               * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+static void st_CloseUsedVariables(const CONTEXT Context, LIST NodeList)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  for (; list_Exist(NodeList); NodeList = list_Cdr(NodeList)) {
+    SUBST Subst;
+
+    for (Subst = ((st_INDEX)list_Car(NodeList))->subst;
+	 subst_Exist(Subst);
+	 Subst = subst_Next(Subst))
+      if (!cont_VarIsUsed(Context, subst_Dom(Subst)))
+	cont_CreateClosedBinding(Context, subst_Dom(Subst));
+
+    if (!st_IsLeaf((st_INDEX)list_Car(NodeList)))
+      st_CloseUsedVariables(Context, ((st_INDEX)list_Car(NodeList))->subnodes);
+  }
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  HEURISTICS FOR INSERTION OF TERMS AND SUBSTS.         * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+static st_INDEX st_FirstVariant(const CONTEXT Context, LIST Subnodes, st_INDEX* BestNonVariant)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  st_INDEX EmptyVariant;
+
+  for (EmptyVariant = NULL, *BestNonVariant = NULL;
+       list_Exist(Subnodes);
+       Subnodes = list_Cdr(Subnodes)) {
+    st_INDEX CurrentNode;
+
+    CurrentNode = (st_INDEX)list_Car(Subnodes);
+
+    cont_StartBinding();
+
+    if (subst_Variation(Context, CurrentNode->subst)) {
+      if (subst_Exist(CurrentNode->subst)) {	
+	subst_CloseVariables(Context, CurrentNode->subst);
+
+	return CurrentNode;
+      } else
+	EmptyVariant = CurrentNode;
+
+    } else if (*BestNonVariant == NULL)
+      if (subst_MatchTops(Context, CurrentNode->subst))
+	*BestNonVariant = CurrentNode;
+
+    cont_BackTrack();
+  }
+
+  return EmptyVariant;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  INSERTION OF TERMS                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+void st_EntryCreate(st_INDEX StIndex, POINTER Pointer, TERM Term, const CONTEXT Context)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  st_INDEX  Current;
+  st_INDEX  BestNonVariant;
+  SYMBOL    FirstDomain;
+  st_MINMAX MinMax;
+
+  cont_Check();
+
+  MinMax = term_ComputeSize(Term);
+
+  /* CREATE INITIAL BINDING AND INITIALIZE LOCAL VARIABLES */
+  FirstDomain = cont_NextIndexVariable(Context);
+  cont_CreateBinding(Context, FirstDomain, Context, Term);
+
+  Current = StIndex;
+
+  if (st_Max(Current) < MinMax)
+    st_SetMax(Current, MinMax);
+  else if (st_Min(Current) > MinMax)
+    st_SetMin(Current, MinMax);
+
+  /* FIND "LAST" VARIATION */
+  while (!st_IsLeaf(Current) &&
+	 (Current = st_FirstVariant(Context, Current->subnodes, &BestNonVariant))) {
+    if (st_Max(Current) < MinMax)
+      st_SetMax(Current, MinMax);
+    else if (st_Min(Current) > MinMax)
+      st_SetMin(Current, MinMax);
+    
+    StIndex = Current;
+  }
+
+  if (cont_BindingsSinceLastStart()==0 && Current && st_IsLeaf(Current)) {
+    
+    /* INSERT ENTRY EQUAL MODULO RENAMING */
+    Current->entries = list_Cons(Pointer, Current->entries);
+  
+  } else if (BestNonVariant) {
+    
+    /* CREATE INNER NODE AND A NEW LEAF */
+    SUBST ComGen, SubstOld, SubstNew;
+
+    if (!st_IsLeaf(BestNonVariant))
+      st_CloseUsedVariables(Context, BestNonVariant->subnodes);
+
+    ComGen = subst_ComGen(Context, BestNonVariant->subst, &SubstOld, &SubstNew);
+
+    st_NodeAddInner(BestNonVariant,
+		    SubstOld,
+		    subst_CloseOpenVariables(SubstNew),
+		    ComGen,
+		    MinMax,
+		    Pointer);
+    
+  } else
+    
+    /* ADD A SINGLE LEAF NODE TO FATHER */
+    StIndex->subnodes =
+      list_Cons(st_NodeAddLeaf(subst_CloseOpenVariables(subst_Nil()), MinMax,
+			       Pointer),
+		StIndex->subnodes);
+
+  cont_Reset();
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  DELETION OF INDEX                                     * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+void st_IndexDelete(st_INDEX StIndex)
+/**************************************************************
+  INPUT:   A pointer to an existing St-Index.
+  SUMMARY: Deletes the whole index structure.
+***************************************************************/
+{
+  if (StIndex == NULL)
+    return;
+  else if (st_IsLeaf(StIndex))
+    list_Delete(StIndex->entries);
+  else
+    /* Recursion */
+    list_DeleteWithElement(StIndex->subnodes, (void (*)(POINTER))st_IndexDelete);
+
+  subst_Delete(StIndex->subst);
+  st_Free(StIndex);
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  DELETION OF ENTRY FOR TERMS                           * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+static st_INDEX st_EntryDeleteHelp(const CONTEXT Context, st_INDEX StIndex, POINTER Pointer,
+				   BOOL* Found)
+/**************************************************************
+  INPUT:   The root of an abstraction tree (StIndex), a
+           pointer to a specific entry of the tree and
+           a query term.
+  RETURNS: Nothing.
+  SUMMARY: Uses Term in order to find Pointer in the tree.
+  EFFECTS: Will delete nodes of StIndex.
+***************************************************************/
+{
+  if (st_IsLeaf(StIndex)) {
+
+    *Found = list_DeleteFromList(&(StIndex->entries), Pointer);
+
+    if (list_Exist(StIndex->entries))
+      return StIndex;
+    else {
+      subst_Delete(StIndex->subst);
+      st_Free(StIndex);
+
+      return NULL;
+    }
+
+  } else {
+
+    LIST Subnodes;
+
+    for (Subnodes = StIndex->subnodes;
+	 list_Exist(Subnodes);
+	 Subnodes = list_Cdr(Subnodes)) {
+      st_INDEX CurrentNode;
+
+      CurrentNode = (st_INDEX)list_Car(Subnodes);
+
+      cont_StartBinding();
+
+      if (subst_Variation(Context, CurrentNode->subst)) {
+	list_Rplaca(Subnodes, st_EntryDeleteHelp(Context,
+						 CurrentNode,
+						 Pointer,
+						 Found));
+	if (*Found) {
+	  if (list_DeleteFromList(&(StIndex->subnodes), NULL))
+	    if (list_Empty(list_Cdr(StIndex->subnodes))) {
+	      /* 'StIndex' has one subnode only. */
+	      st_NodeMergeWithSon(StIndex);
+	  
+	      return StIndex;
+	    }
+
+	  /* Assertion: 'StIndex' is an inner node. */
+
+	  CurrentNode      = (st_INDEX)list_Car(StIndex->subnodes);
+	  st_SetMax(StIndex, st_Max(CurrentNode));
+	  st_SetMin(StIndex, st_Min(CurrentNode));
+
+	  for (Subnodes = list_Cdr(StIndex->subnodes);
+	       list_Exist(Subnodes);
+	       Subnodes = list_Cdr(Subnodes)) {
+	    CurrentNode = (st_INDEX)list_Car(Subnodes);
+
+	    if (st_Max(CurrentNode) > st_Max(StIndex))
+	      st_SetMax(StIndex, st_Max(CurrentNode));
+
+	    if (st_Min(CurrentNode) < st_Min(StIndex))
+	      st_SetMin(StIndex, st_Min(CurrentNode));
+	  }
+
+	  return StIndex;
+	}
+      }
+
+      cont_BackTrack();
+    }
+
+    return StIndex;
+  }
+}
+
+
+BOOL st_EntryDelete(st_INDEX StIndex, POINTER Pointer, TERM Term, const CONTEXT Context)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{ 
+  BOOL   Found;
+  LIST   Subnodes;
+  SYMBOL FirstDomain;
+
+  cont_Check();
+
+  FirstDomain = symbol_FirstIndexVariable();
+  cont_CreateBinding(Context, FirstDomain, Context, Term);
+
+  for (Found = FALSE, Subnodes = StIndex->subnodes;
+       list_Exist(Subnodes);
+       Subnodes = list_Cdr(Subnodes)) {
+    st_INDEX CurrentNode;
+
+    CurrentNode = (st_INDEX)list_Car(Subnodes);
+
+    cont_StartBinding();
+
+    if (subst_Variation(Context, CurrentNode->subst)) {
+      list_Rplaca(Subnodes, st_EntryDeleteHelp(Context, CurrentNode, Pointer, &Found));
+
+      if (Found) {
+	StIndex->subnodes = list_PointerDeleteElement(StIndex->subnodes, NULL);
+
+	if (list_Exist(StIndex->subnodes)) {
+	  CurrentNode       = (st_INDEX)list_Car(StIndex->subnodes);
+	  st_SetMax(StIndex, st_Max(CurrentNode));
+	  st_SetMin(StIndex, st_Min(CurrentNode));
+
+	  for (Subnodes = list_Cdr(StIndex->subnodes);
+	       list_Exist(Subnodes);
+	       Subnodes = list_Cdr(Subnodes)) {
+	    CurrentNode = (st_INDEX)list_Car(Subnodes);
+
+	    if (st_Max(CurrentNode) > st_Max(StIndex))
+	      st_SetMax(StIndex, st_Max(CurrentNode));
+
+	    if (st_Min(CurrentNode) < st_Min(StIndex))
+	      st_SetMin(StIndex, st_Min(CurrentNode));
+	  }
+	} else {
+	  st_SetMax(StIndex, 0);
+	  st_SetMin(StIndex, 0);
+	}
+
+	break;
+      }
+    }
+
+    cont_BackTrack();
+  }
+
+  cont_Reset();
+
+  return Found;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  RETRIEVAL FOR TERMS                                   * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+static LIST st_TraverseTreeUnifier(CONTEXT IndexContext, st_INDEX StIndex)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  int      Save;
+  LIST     Result, CurrentList;
+  st_INDEX CurrentNode;
+
+  /* PREPARE TRAVERSAL */
+  Save = stack_Bottom();
+
+  Result      = list_Nil();
+  CurrentList = StIndex->subnodes;
+  
+  cont_StartBinding();
+
+  for (;;) {
+    
+    /* BACKTRACK A BIG STEP */
+    if (list_Empty(CurrentList)) {
+      cont_StopAndBackTrack();
+
+      if (stack_Empty(Save))
+	return Result;
+
+      CurrentList = stack_PopResult();
+    }
+    
+    /* DESCENDING */
+    for (CurrentNode = (st_INDEX)list_Car(CurrentList);
+	 subst_Unify(IndexContext, CurrentNode->subst);
+	 CurrentList = CurrentNode->subnodes,
+	 CurrentNode = (st_INDEX)list_Car(CurrentList))
+      if (st_IsLeaf(CurrentNode)) {
+	Result = list_Append(CurrentNode->entries, Result);
+	break;
+      } else if (list_Exist(list_Cdr(CurrentList))) {
+	stack_Push(list_Cdr(CurrentList));
+	cont_StartBinding();
+      } else
+	cont_StopAndStartBinding();
+    
+    /* BACKTRACK LEAF OR INNER NODE */
+    CurrentList = list_Cdr(CurrentList);
+    cont_BackTrackAndStart();
+  }
+}
+
+
+static LIST st_TraverseTreeGen(CONTEXT IndexContext, st_INDEX StIndex)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  int      Save;
+  LIST     Result, CurrentList;
+  st_INDEX CurrentNode;
+
+  /* PREPARE TRAVERSAL */
+  Save = stack_Bottom();
+
+  Result      = list_Nil();
+  CurrentList = StIndex->subnodes;
+
+  cont_StartBinding();
+  
+  for (;;) {
+    
+    /* BACKTRACK A BIG STEP */
+    if (list_Empty(CurrentList)) {
+      cont_StopAndBackTrack();
+
+      if (stack_Empty(Save))
+	return Result;
+
+      CurrentList = stack_PopResult();
+    }
+    
+    /* DESCENDING */
+    for (CurrentNode = (st_INDEX)list_Car(CurrentList);
+	 subst_Match(IndexContext, CurrentNode->subst);
+	 CurrentList = CurrentNode->subnodes,
+	 CurrentNode = (st_INDEX)list_Car(CurrentList))
+      if (st_IsLeaf(CurrentNode)) {
+	Result = list_Append(CurrentNode->entries, Result);
+	break;
+      } else if (list_Cdr(CurrentList)) {
+	stack_Push(list_Cdr(CurrentList));
+	cont_StartBinding();
+      } else
+	cont_StopAndStartBinding();
+    
+    /* BACKTRACK LEAF OR INNER NODE */
+    CurrentList = list_Cdr(CurrentList);
+    cont_BackTrackAndStart();
+  }
+}
+
+
+static LIST st_TraverseTreeInstance(CONTEXT IndexContext, st_INDEX StIndex)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  int      Save;
+  LIST     Result, CurrentList;
+  st_INDEX CurrentNode;
+
+  /* PREPARE TRAVERSAL */
+  Save = stack_Bottom();
+
+  Result      = list_Nil();
+  CurrentList = StIndex->subnodes;
+
+  cont_StartBinding();
+
+  for (;;) {
+    
+    /* BACKTRACK A BIG STEP */
+    if (list_Empty(CurrentList)) {
+      cont_StopAndBackTrack();
+
+      if (stack_Empty(Save))
+	return Result;
+
+      CurrentList = stack_PopResult();
+    }
+    
+    /* DESCENDING */
+    for (CurrentNode = (st_INDEX)list_Car(CurrentList);
+	 subst_MatchReverse(IndexContext, CurrentNode->subst);
+	 CurrentList = CurrentNode->subnodes,
+	 CurrentNode = (st_INDEX)list_Car(CurrentList))
+      if (st_IsLeaf(CurrentNode)) {
+	Result = list_Append(CurrentNode->entries, Result);
+	break;
+      } else if (list_Cdr(CurrentList)) {
+	stack_Push(list_Cdr(CurrentList));
+	cont_StartBinding();
+      } else
+	cont_StopAndStartBinding();
+    
+    /* BACKTRACK LEAF OR INNER NODE */
+    CurrentList = list_Cdr(CurrentList);
+    cont_BackTrackAndStart();
+  }
+}
+
+
+static LIST st_TraverseTreeGenPreTest(CONTEXT IndexContext,
+				      st_INDEX StIndex,
+				      st_MINMAX MinMax)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  int      Save;
+  LIST     Result, CurrentList;
+  st_INDEX CurrentNode;
+
+  /* PREPARE TRAVERSAL */
+  Save = stack_Bottom();
+
+  Result      = list_Nil();
+  CurrentList = StIndex->subnodes;
+
+  cont_StartBinding();
+
+  for (;;) {
+    
+    /* BACKTRACK A BIG STEP */
+    if (list_Empty(CurrentList)) {
+      cont_StopAndBackTrack();
+
+      if (stack_Empty(Save))
+	return Result;
+
+      CurrentList = stack_PopResult();
+    }
+    
+    /* DESCENDING */
+    for (CurrentNode = (st_INDEX)list_Car(CurrentList);
+	 (MinMax >= st_Min(CurrentNode)) &&
+	   subst_Match(IndexContext, CurrentNode->subst);
+	 CurrentList = CurrentNode->subnodes,
+	 CurrentNode = (st_INDEX)list_Car(CurrentList))
+      if (st_IsLeaf(CurrentNode)) {
+	Result = list_Append(CurrentNode->entries, Result);
+	break;
+      } else if (list_Cdr(CurrentList)) {
+	stack_Push(list_Cdr(CurrentList));
+    	cont_StartBinding();
+      } else
+	cont_StopAndStartBinding();
+
+    /* BACKTRACK LEAF OR INNER NODE */
+    CurrentList = list_Cdr(CurrentList);
+    cont_BackTrackAndStart();
+  }
+}
+
+
+static LIST st_TraverseTreeInstancePreTest(CONTEXT IndexContext, st_INDEX StIndex, st_MINMAX MinMax)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  int      Save;
+  LIST     Result, CurrentList;
+  st_INDEX CurrentNode;
+
+  /* PREPARE TRAVERSAL */
+  Save = stack_Bottom();
+
+  Result      = list_Nil();
+  CurrentList = StIndex->subnodes;
+
+  cont_StartBinding();
+
+  for (;;) {
+    
+    /* BACKTRACK A BIG STEP */
+    if (list_Empty(CurrentList)) {
+      cont_StopAndBackTrack();
+
+      if (stack_Empty(Save))
+	return Result;
+
+      CurrentList = stack_PopResult();
+    }
+    
+    /* DESCENDING */
+    for (CurrentNode = (st_INDEX)list_Car(CurrentList);
+	 (MinMax <= st_Max(CurrentNode)) &&
+	   subst_MatchReverse(IndexContext, CurrentNode->subst);
+	 CurrentList = CurrentNode->subnodes,
+	 CurrentNode = (st_INDEX)list_Car(CurrentList))
+      if (st_IsLeaf(CurrentNode)) {
+	Result = list_Append(CurrentNode->entries, Result);
+	break;
+      } else if (list_Cdr(CurrentList)) {
+	stack_Push(list_Cdr(CurrentList));
+    	cont_StartBinding();
+      } else
+	cont_StopAndStartBinding();
+
+    /* BACKTRACK LEAF OR INNER NODE */
+    CurrentList = list_Cdr(CurrentList);
+    cont_BackTrackAndStart();
+  }
+}
+
+
+LIST st_GetUnifier(CONTEXT IndexContext, st_INDEX StIndex, CONTEXT TermContext, TERM Term)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  LIST   Result;
+  SYMBOL FirstDomain;
+
+  cont_Check();
+
+  FirstDomain = symbol_FirstIndexVariable();
+  cont_CreateBinding(IndexContext, FirstDomain, TermContext, Term);
+
+  Result = st_TraverseTreeUnifier(IndexContext, StIndex);
+
+  cont_Reset();
+  
+  return Result;
+}
+
+
+LIST st_GetGen(CONTEXT IndexContext, st_INDEX StIndex, TERM Term)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  LIST   Result;
+  SYMBOL FirstDomain;
+
+  cont_Check();
+
+  FirstDomain = symbol_FirstIndexVariable();
+  cont_CreateBinding(IndexContext, FirstDomain, cont_InstanceContext(), Term);
+
+  Result = st_TraverseTreeGen(IndexContext, StIndex);
+
+  cont_Reset();
+  
+  return Result;
+}
+
+
+LIST st_GetGenPreTest(CONTEXT IndexContext, st_INDEX StIndex, TERM Term)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  LIST   Result;
+  SYMBOL FirstDomain;
+
+  cont_Check();
+
+  FirstDomain = symbol_FirstIndexVariable();
+  cont_CreateBinding(IndexContext, FirstDomain, cont_InstanceContext(), Term);
+
+  Result = st_TraverseTreeGenPreTest(IndexContext, StIndex, term_ComputeSize(Term));
+
+  cont_Reset();
+  
+  return Result;
+}
+
+
+LIST st_GetInstance(CONTEXT IndexContext, st_INDEX StIndex, TERM Term)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  LIST   Result;
+  SYMBOL FirstDomain;
+
+  cont_Check();
+
+  FirstDomain = symbol_FirstIndexVariable();
+  cont_CreateBinding(IndexContext, FirstDomain, IndexContext, Term);
+
+  Result = st_TraverseTreeInstance(IndexContext, StIndex);
+
+  cont_Reset();
+  
+  return Result;
+}
+
+
+LIST st_GetInstancePreTest(CONTEXT IndexContext, st_INDEX StIndex, TERM Term)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  LIST   Result;
+  SYMBOL FirstDomain;
+
+  cont_Check();
+
+  FirstDomain = symbol_FirstIndexVariable();
+  cont_CreateBinding(IndexContext, FirstDomain, IndexContext, Term);
+
+  Result = st_TraverseTreeInstancePreTest(IndexContext, StIndex, term_ComputeSize(Term));
+
+  cont_Reset();
+  
+  return Result;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  INCREMENTAL RETRIEVAL                                 * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+static POINTER st_TraverseForExistUnifier(CONTEXT IndexContext)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  LIST     CurrentList;
+  st_INDEX CurrentNode;
+
+  /* Caution: In case an entry is found
+     the procedure returns immediately
+     without backtracking the current bindings. */
+
+  CurrentList = list_Nil();
+  
+  for (;;) {
+    
+    /* BACKTRACK A BIG STEP */
+    if (list_Empty(CurrentList)) {
+      cont_StopAndBackTrack();
+
+      if (st_StackEmpty(st_STACKSAVE))
+	return NULL;
+
+      CurrentList = st_StackPopResult();
+    }
+    
+    /* DESCENDING */
+    for (CurrentNode = (st_INDEX)list_Car(CurrentList);
+	 subst_Unify(IndexContext, CurrentNode->subst);
+	 CurrentList = CurrentNode->subnodes,
+	 CurrentNode = (st_INDEX)list_Car(CurrentList)) {
+      if (list_Exist(list_Cdr(CurrentList))) {
+	st_StackPush(list_Cdr(CurrentList));
+	cont_StartBinding();
+      } else
+	cont_StopAndStartBinding();
+    
+      if (st_IsLeaf(CurrentNode)) {
+	st_StackPush(list_Cdr(CurrentNode->entries));
+	return list_Car(CurrentNode->entries);
+      }
+    }
+    
+    /* BACKTRACK LEAF OR INNER NODE */
+    CurrentList = list_Cdr(CurrentList);
+    cont_BackTrackAndStart();
+  }
+}
+
+
+static POINTER st_TraverseForExistGen(CONTEXT IndexContext)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  LIST     CurrentList;
+  st_INDEX CurrentNode;
+
+  /* Caution: In case an entry is found
+     the procedure returns immediately
+     without backtracking the current bindings. */
+
+  CurrentList = list_Nil();
+  
+  for (;;) {
+    
+    /* BACKTRACK A BIG STEP */
+    if (list_Empty(CurrentList)) {
+      cont_StopAndBackTrack();
+
+      if (st_StackEmpty(st_STACKSAVE))
+	return NULL;
+
+      CurrentList = st_StackPopResult();
+    }
+    
+    /* DESCENDING */
+    for (CurrentNode = (st_INDEX)list_Car(CurrentList);
+	 subst_Match(IndexContext, CurrentNode->subst);
+	 CurrentList = CurrentNode->subnodes,
+	 CurrentNode = (st_INDEX)list_Car(CurrentList)) {
+      if (list_Exist(list_Cdr(CurrentList))) {
+	st_StackPush(list_Cdr(CurrentList));
+	cont_StartBinding();
+      } else
+	cont_StopAndStartBinding();
+
+      if (st_IsLeaf(CurrentNode)) {
+	st_StackPush(list_Cdr(CurrentNode->entries));
+	return list_Car(CurrentNode->entries);
+      }
+    }
+    
+    /* BACKTRACK LEAF OR INNER NODE */
+    CurrentList = list_Cdr(CurrentList);
+    cont_BackTrackAndStart();
+  }
+}
+
+
+static POINTER st_TraverseForExistGenPreTest(CONTEXT IndexContext)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  LIST     CurrentList;
+  st_INDEX CurrentNode;
+
+  /* Caution: In case an entry is found
+     the procedure returns immediately
+     without backtracking the current bindings. */
+
+  CurrentList = list_Nil();
+  
+  for (;;) {
+    
+    /* BACKTRACK A BIG STEP */
+    if (list_Empty(CurrentList)) {
+      cont_StopAndBackTrack();
+
+      if (st_StackEmpty(st_STACKSAVE))
+	return NULL;
+
+      CurrentList = st_StackPopResult();
+    }
+    
+    /* DESCENDING */
+    for (CurrentNode = (st_INDEX)list_Car(CurrentList);
+	 (st_EXIST_MINMAX >= st_Min(CurrentNode)) &&
+	   subst_Match(IndexContext, CurrentNode->subst);
+	 CurrentList = CurrentNode->subnodes,
+	 CurrentNode = (st_INDEX)list_Car(CurrentList)) {
+      if (list_Exist(list_Cdr(CurrentList))) {
+	st_StackPush(list_Cdr(CurrentList));
+	cont_StartBinding();
+      } else
+	cont_StopAndStartBinding();
+
+      if (st_IsLeaf(CurrentNode)) {
+	st_StackPush(list_Cdr(CurrentNode->entries));
+	return list_Car(CurrentNode->entries);
+      }
+    }
+    
+    /* BACKTRACK LEAF OR INNER NODE */
+    CurrentList = list_Cdr(CurrentList);
+    cont_BackTrackAndStart();
+  }
+}
+
+
+static POINTER st_TraverseForExistInstance(CONTEXT IndexContext)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  LIST     CurrentList;
+  st_INDEX CurrentNode;
+
+  /* Caution: In case an entry is found
+     the procedure returns immediately
+     without backtracking the current bindings. */
+
+  CurrentList = list_Nil();
+  
+  for (;;) {
+    
+    /* BACKTRACK A BIG STEP */
+    if (list_Empty(CurrentList)) {
+      cont_StopAndBackTrack();
+
+      if (st_StackEmpty(st_STACKSAVE))
+	return NULL;
+
+      CurrentList = st_StackPopResult();
+    }
+    
+    /* DESCENDING */
+    for (CurrentNode = (st_INDEX)list_Car(CurrentList);
+	 subst_MatchReverse(IndexContext, CurrentNode->subst);
+	 CurrentList = CurrentNode->subnodes,
+	 CurrentNode = (st_INDEX)list_Car(CurrentList)) {
+      if (list_Exist(list_Cdr(CurrentList))) {
+	st_StackPush(list_Cdr(CurrentList));
+	cont_StartBinding();
+      } else
+	cont_StopAndStartBinding();
+
+      if (st_IsLeaf(CurrentNode)) {
+	st_StackPush(list_Cdr(CurrentNode->entries));
+	return list_Car(CurrentNode->entries);
+      }
+    }
+    
+    /* BACKTRACK LEAF OR INNER NODE */
+    CurrentList = list_Cdr(CurrentList);
+    cont_BackTrackAndStart();
+  }
+}
+
+
+static POINTER st_TraverseForExistInstancePreTest(CONTEXT IndexContext)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  LIST     CurrentList;
+  st_INDEX CurrentNode;
+
+  /* Caution: In case an entry is found
+     the procedure returns immediately
+     without backtracking the current bindings. */
+
+  CurrentList = list_Nil();
+  
+  for (;;) {
+    
+    /* BACKTRACK A BIG STEP */
+    if (list_Empty(CurrentList)) {
+      cont_StopAndBackTrack();
+
+      if (st_StackEmpty(st_STACKSAVE))
+	return NULL;
+
+      CurrentList = st_StackPopResult();
+    }
+    
+    /* DESCENDING */
+    for (CurrentNode = (st_INDEX)list_Car(CurrentList);
+	 (st_EXIST_MINMAX <= st_Max(CurrentNode)) &&
+	     subst_MatchReverse(IndexContext, CurrentNode->subst);
+	 CurrentList = CurrentNode->subnodes,
+	 CurrentNode = (st_INDEX)list_Car(CurrentList)) {
+      if (list_Exist(list_Cdr(CurrentList))) {
+	st_StackPush(list_Cdr(CurrentList));
+	cont_StartBinding();
+      } else
+	cont_StopAndStartBinding();
+
+      if (st_IsLeaf(CurrentNode)) {
+	st_StackPush(list_Cdr(CurrentNode->entries));
+	return list_Car(CurrentNode->entries);
+      }
+    }
+    
+    /* BACKTRACK LEAF OR INNER NODE */
+    CurrentList = list_Cdr(CurrentList);
+    cont_BackTrackAndStart();
+  }
+}
+
+
+void st_CancelExistRetrieval(void)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  if (st_CURRENT_RETRIEVAL != st_NOP) {
+
+#ifdef CHECK
+    cont_CheckState();
+#endif
+
+    st_StackSetBottom(st_STACKSAVE);
+
+    switch (st_WHICH_CONTEXTS) {
+
+    case st_STANDARD:
+      cont_Reset();
+      break;
+
+    case st_NOC:
+      break;
+
+    default:
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In st_CancelExistRetrieval: Unknown context type.\n");
+      misc_FinishErrorReport();
+    }
+
+    st_CURRENT_RETRIEVAL = st_NOP;
+    st_WHICH_CONTEXTS    = st_NOC;
+    st_INDEX_CONTEXT     = NULL;
+    st_EXIST_MINMAX      = 0;
+  }
+}
+
+
+POINTER st_ExistUnifier(CONTEXT IndexContext, st_INDEX StIndex, CONTEXT TermContext, TERM Term)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  SYMBOL  FirstDomain;
+  POINTER Result;
+
+#ifdef CHECK
+  if (!st_StackEmpty(st_STACKSAVE)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In st_ExistUnifier: ST-Stack not empty.\n");
+    misc_FinishErrorReport();
+  } else if (st_CURRENT_RETRIEVAL != st_NOP) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In st_ExistUnifier: %d Retrieval already in progress.\n",
+		     st_CURRENT_RETRIEVAL);
+    misc_FinishErrorReport();
+  }
+#endif
+
+  cont_Check();
+
+  if (st_Exist(StIndex)) {
+
+    st_CURRENT_RETRIEVAL = st_UNIFIER;
+    st_WHICH_CONTEXTS    = st_STANDARD;
+    st_INDEX_CONTEXT     = IndexContext;
+
+    st_STACKSAVE = st_StackBottom();
+
+    FirstDomain = symbol_FirstIndexVariable();
+    cont_CreateBinding(IndexContext, FirstDomain, TermContext, Term);
+
+    cont_StartBinding();
+    st_StackPush(StIndex->subnodes);
+    cont_StartBinding();
+
+    Result = st_TraverseForExistUnifier(IndexContext);
+
+#ifdef CHECK
+    cont_SaveState();
+#endif
+
+    if (Result == NULL)
+      st_CancelExistRetrieval();
+
+    return Result;
+  } else
+    return NULL;
+}
+
+
+POINTER st_ExistGen(CONTEXT IndexContext, st_INDEX StIndex, TERM Term)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  SYMBOL  FirstDomain;
+  POINTER Result;
+
+#ifdef CHECK
+  if (!st_StackEmpty(st_STACKSAVE)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In st_ExistGen: ST-Stack not empty.\n");
+    misc_FinishErrorReport();
+  } 
+  else 
+    if (st_CURRENT_RETRIEVAL != st_NOP) {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In st_ExistGen: %d Retrieval already in progress.\n",
+		       st_CURRENT_RETRIEVAL);
+      misc_FinishErrorReport();
+    }
+#endif
+
+  cont_Check();
+
+  if (st_Exist(StIndex)) {
+
+    st_CURRENT_RETRIEVAL = st_GEN;
+    st_WHICH_CONTEXTS    = st_STANDARD;
+    st_INDEX_CONTEXT     = IndexContext;
+  
+    st_STACKSAVE = st_StackBottom();
+
+    FirstDomain = symbol_FirstIndexVariable();
+    cont_CreateBinding(IndexContext, FirstDomain, cont_InstanceContext(), Term);
+
+    cont_StartBinding();
+    st_StackPush(StIndex->subnodes);
+    cont_StartBinding();
+
+    Result = st_TraverseForExistGen(IndexContext);
+
+#ifdef CHECK
+    cont_SaveState();
+#endif
+
+    if (Result == NULL)
+      st_CancelExistRetrieval();
+
+    return Result;
+  } else
+    return NULL;
+}
+
+
+POINTER st_ExistGenPreTest(CONTEXT IndexContext, st_INDEX StIndex, TERM Term)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  SYMBOL  FirstDomain;
+  POINTER Result;
+
+#ifdef CHECK
+  if (!st_StackEmpty(st_STACKSAVE)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In st_ExistGenPreTest: ST-Stack not empty.\n");
+    misc_FinishErrorReport();
+  } 
+  else 
+    if (st_CURRENT_RETRIEVAL != st_NOP) {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In st_ExistGenPreTest: %d Retrieval already in progress.\n",
+		       st_CURRENT_RETRIEVAL);
+      misc_FinishErrorReport();
+    }
+#endif
+
+  cont_Check();
+
+  if (st_Exist(StIndex)) {
+
+    st_CURRENT_RETRIEVAL = st_GENPRETEST;
+    st_WHICH_CONTEXTS    = st_STANDARD;
+    st_INDEX_CONTEXT     = IndexContext;
+  
+    st_STACKSAVE = st_StackBottom();
+
+
+    FirstDomain     = symbol_FirstIndexVariable();
+    st_EXIST_MINMAX = term_ComputeSize(Term);
+    cont_CreateBinding(IndexContext, FirstDomain, IndexContext, Term);
+
+    cont_StartBinding();
+    st_StackPush(StIndex->subnodes);
+    cont_StartBinding();
+
+    Result = st_TraverseForExistGenPreTest(IndexContext);
+
+#ifdef CHECK
+    cont_SaveState();
+#endif
+
+    if (Result == NULL)
+      st_CancelExistRetrieval();
+
+    return Result;
+  } else
+    return NULL;
+}
+
+
+POINTER st_ExistInstance(CONTEXT IndexContext, st_INDEX StIndex, TERM Term)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  SYMBOL  FirstDomain;
+  POINTER Result;
+
+#ifdef CHECK
+  if (!st_StackEmpty(st_STACKSAVE)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In st_ExistInstance: ST-Stack not empty.\n");
+    misc_FinishErrorReport();
+  } 
+  else 
+    if (st_CURRENT_RETRIEVAL != st_NOP) {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In st_ExistInstance: %d Retrieval already in progress.\n",
+		       st_CURRENT_RETRIEVAL);
+      misc_FinishErrorReport();
+    }
+#endif
+
+  cont_Check();
+
+  if (st_Exist(StIndex)) {
+
+    st_CURRENT_RETRIEVAL = st_INSTANCE;
+    st_WHICH_CONTEXTS    = st_STANDARD;
+    st_INDEX_CONTEXT     = IndexContext;
+
+    st_STACKSAVE = st_StackBottom();
+
+    FirstDomain = symbol_FirstIndexVariable();
+    cont_CreateBinding(IndexContext, FirstDomain, IndexContext, Term);
+
+    cont_StartBinding();
+    st_StackPush(StIndex->subnodes);
+    cont_StartBinding();
+
+    Result = st_TraverseForExistInstance(IndexContext);
+
+#ifdef CHECK
+    cont_SaveState();
+#endif
+
+    if (Result == NULL)
+      st_CancelExistRetrieval();
+
+    return Result;
+  } else
+    return NULL;
+}
+
+
+POINTER st_ExistInstancePreTest(CONTEXT IndexContext, st_INDEX StIndex, TERM Term)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  SYMBOL  FirstDomain;
+  POINTER Result;
+
+#ifdef CHECK
+  if (!st_StackEmpty(st_STACKSAVE)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In st_ExistInstancePreTest: ST-Stack not empty.\n");
+    misc_FinishErrorReport();
+  } 
+  else 
+    if (st_CURRENT_RETRIEVAL != st_NOP) {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In st_ExistInstancePreTest: %d Retrieval already in progress.\n",
+		       st_CURRENT_RETRIEVAL);
+      misc_FinishErrorReport();
+    }
+#endif
+
+  cont_Check();
+
+  if (st_Exist(StIndex)) {
+
+    st_CURRENT_RETRIEVAL = st_INSTANCEPRETEST;
+    st_WHICH_CONTEXTS    = st_STANDARD;
+    st_INDEX_CONTEXT     = IndexContext;
+
+    st_STACKSAVE = st_StackBottom();
+
+    FirstDomain     = symbol_FirstIndexVariable();
+    st_EXIST_MINMAX = term_ComputeSize(Term);
+    cont_CreateBinding(IndexContext, FirstDomain, IndexContext, Term);
+
+    cont_StartBinding();
+    st_StackPush(StIndex->subnodes);
+    cont_StartBinding();
+
+    Result = st_TraverseForExistInstancePreTest(IndexContext);
+
+#ifdef CHECK
+    cont_SaveState();
+#endif
+
+    if (Result == NULL)
+      st_CancelExistRetrieval();
+
+    return Result;
+  } else
+    return NULL;
+}
+
+
+POINTER st_NextCandidate(void)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECTS: 
+***************************************************************/
+{
+  LIST Result;
+
+#ifdef CHECK
+  if (st_StackEmpty(st_STACKSAVE)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In st_NextCandidate: ST-Stack empty.\n");
+    misc_FinishErrorReport();
+  } 
+  else 
+    if (st_CURRENT_RETRIEVAL == st_NOP) {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In st_NextCandidate: No retrieval in progress.\n");
+      misc_FinishErrorReport();
+    }
+
+  cont_CheckState();
+#endif
+
+  Result = st_StackPopResult();
+
+  if (list_Exist(Result)) {
+    st_StackPush(list_Cdr(Result));
+#ifdef CHECK
+    cont_SaveState();
+#endif
+    return list_Car(Result);
+  } else {
+    POINTER NewResult;
+
+    NewResult = NULL;
+
+    if (st_WHICH_CONTEXTS == st_STANDARD)
+      switch (st_CURRENT_RETRIEVAL) {
+
+      case st_UNIFIER:
+	NewResult = st_TraverseForExistUnifier(st_INDEX_CONTEXT);
+	break;
+
+      case st_GEN:
+	NewResult = st_TraverseForExistGen(st_INDEX_CONTEXT);
+	break;
+
+      case st_GENPRETEST:
+	NewResult = st_TraverseForExistGenPreTest(st_INDEX_CONTEXT);
+	break;
+
+      case st_INSTANCE:
+	NewResult = st_TraverseForExistInstance(st_INDEX_CONTEXT);
+	break;
+
+      case st_INSTANCEPRETEST:
+	NewResult = st_TraverseForExistInstancePreTest(st_INDEX_CONTEXT);
+
+      default:
+	misc_StartErrorReport();
+	misc_ErrorReport("\n In st_NextCandidate: Unknown retrieval type.\n");
+	misc_FinishErrorReport();
+      }
+    else {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In st_NextCandidate: Unknown context type.\n");
+      misc_FinishErrorReport();
+    }
+
+#ifdef CHECK
+    cont_SaveState();
+#endif
+
+    if (NewResult == NULL)
+      st_CancelExistRetrieval();
+
+    return NewResult;
+  }
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  OUTPUT                                                * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+static void st_PrintHelp(st_INDEX St, int Position, void (*Print)(POINTER))
+/**************************************************************
+  INPUT:   A node of an St, an indention and a print
+           function for the entries.
+  SUMMARY: Prints an St starting at node St.
+***************************************************************/
+{
+  int i;
+  
+  if (St == (st_INDEX)NULL)
+    return;
+  
+  for (i = 0; i < Position; i++)
+    putchar(' ');
+  puts("|");
+  
+  for (i = 0; i < Position; i++)
+    putchar(' ');
+  fputs("+-", stdout);
+
+  printf(" Max: %d, Min: %d, ", st_Max(St), st_Min(St));
+  subst_Print(St->subst);
+  putchar('\n');
+
+  if (st_IsLeaf(St)) {
+
+    LIST Scan;
+
+    for (i = 0; i < Position; i++)
+      putchar(' ');
+    fputs("  =>", stdout);
+
+    if (Print)
+      for (Scan = St->entries; Scan != NULL; Scan = list_Cdr(Scan)) {
+	putchar(' ');
+	Print(list_Car(Scan));
+      }
+    else
+      printf(" %d Entries", list_Length(St->entries));
+
+    putchar('\n');
+    
+  } else {
+    LIST Scan;
+
+    for (Scan = St->subnodes; Scan != NULL; Scan = list_Cdr(Scan))
+      st_PrintHelp(list_Car(Scan), Position + 2, Print);
+  }
+}
+
+
+void st_Print(st_INDEX StIndex, void (*Print)(POINTER))
+/**************************************************************
+  INPUT:   The root of an St.
+  SUMMARY: Prints a whole St.
+***************************************************************/
+{
+  LIST Scan;
+
+  if (st_Empty(StIndex)) {
+    puts("\n\nIndex empty.");
+    return;
+  }
+
+  fputs("\n\nroot: ", stdout);
+  printf(" Max: %d, Min: %d, ", st_Max(StIndex), st_Min(StIndex));
+  subst_Print(StIndex->subst);
+  putchar('\n');
+  if (st_IsLeaf(StIndex)) {
+    fputs("  =>", stdout);
+
+    if (Print)
+      for (Scan = StIndex->entries; Scan != NULL; Scan = list_Cdr(Scan)) {
+	putchar(' ');
+	Print(list_Car(Scan));
+      }
+    else
+      printf(" %d Entries", list_Length(StIndex->entries));
+
+  } else
+    for (Scan = StIndex->subnodes; Scan != NULL; Scan = list_Cdr(Scan))
+      st_PrintHelp(list_Car(Scan),2, Print);
+  puts("\n");
+}
diff --git a/test/spass/st.h b/test/spass/st.h
new file mode 100644
index 0000000000000000000000000000000000000000..93f9fb634df4f5938e2953cc1068135f0426ec0b
--- /dev/null
+++ b/test/spass/st.h
@@ -0,0 +1,305 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                    ST INDEXING                         * */
+/* *                                                        * */
+/* *  $Module:   ST                                         * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _ST_
+#define _ST_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "foldfg.h"
+#include "term.h"
+#include "symbol.h"
+#include "list.h"
+
+#include "subst.h"
+#include "unify.h"
+
+/**************************************************************/
+/* Data Structures                                            */
+/**************************************************************/
+
+typedef enum {st_NOP,             st_UNIFIER,    st_GEN,
+	      st_GENPRETEST,      st_INSTANCE,   st_INSTANCEPRETEST
+}  st_RETRIEVAL_TYPE;
+
+typedef enum {st_STANDARD, st_NOC} st_WHERE_TYPE;
+
+typedef unsigned short int st_MINMAX;
+
+
+/**************************************************************/
+/* Type st_INDEX and Inline Functions                         */
+/**************************************************************/
+
+typedef struct st {
+  SUBST     subst;
+  LIST      subnodes;
+  LIST      entries;
+  st_MINMAX max, min;
+} st_INDEX_NODE, *st_INDEX;
+
+
+static __inline__ st_INDEX st_Get(void)
+{
+  return (st_INDEX) memory_Malloc(sizeof(st_INDEX_NODE));
+}
+
+static __inline__ void st_Free(st_INDEX ST)
+{
+  memory_Free(ST, sizeof(st_INDEX_NODE));
+}
+
+static __inline__ SUBST st_Subst(st_INDEX ST)
+{
+  return ST->subst;
+}
+
+static __inline__ LIST st_Entries(st_INDEX ST)
+{
+  return ST->entries;
+}
+
+static __inline__ LIST st_Subnodes(st_INDEX ST)
+{
+  return ST->subnodes;
+}
+
+static __inline__ st_MINMAX st_Max(st_INDEX ST)
+{
+  return ST->max;
+}
+
+static __inline__ void st_SetMax(st_INDEX ST, st_MINMAX Value)
+{
+  ST->max = Value;
+}
+
+static __inline__ st_MINMAX st_Min(st_INDEX ST)
+{
+  return ST->min;
+}
+
+static __inline__ void st_SetMin(st_INDEX ST, st_MINMAX Value)
+{
+  ST->min = Value;
+}
+
+static __inline__ BOOL st_IsLeaf(st_INDEX ST)
+{
+  return !list_Empty(st_Entries(ST));
+}
+
+static __inline__ BOOL st_IsInner(st_INDEX ST)
+{
+  return !list_Empty(st_Subnodes(ST));
+}
+
+static __inline__ BOOL st_Empty(st_INDEX ST)
+{
+  return (ST == NULL || (!st_IsLeaf(ST) && !st_IsInner(ST)));
+}
+
+static __inline__ BOOL st_Exist(st_INDEX ST)
+{
+  return (ST != NULL && (st_IsLeaf(ST) || st_IsInner(ST)));
+}
+
+static __inline__ void st_SetNode(st_INDEX Index, SUBST Subst,
+				  LIST Subnodes, LIST Entries)
+{
+  Index->subst    = Subst;
+  Index->subnodes = Subnodes;
+  Index->entries  = Entries;
+}
+
+static __inline__ st_INDEX st_CreateNode(SUBST Subst, LIST Subnodes,
+					 LIST Entries)
+{
+  st_INDEX index;
+
+  index = st_Get();
+  st_SetNode(index, Subst, Subnodes, Entries);
+
+  return index;
+}
+
+
+typedef enum {st_EMPTY = 1, st_FCT, st_CONST, st_VAR,
+	      st_STAR, st_FIRST} NODETYPE;
+
+
+/**************************************************************/
+/* A special ST-Stack for sequential retrieval operations     */
+/**************************************************************/
+
+#define st_STACKSIZE 1000
+
+typedef POINTER ST_STACK[st_STACKSIZE];
+
+extern ST_STACK st_STACK;
+extern int      st_STACKPOINTER;
+extern int      st_STACKSAVE;
+
+/* Stack operations */
+
+static __inline__ void st_StackInit(void)
+{
+  st_STACKPOINTER = 0;
+}
+
+static __inline__ void st_StackPush(POINTER Entry)
+{
+#ifdef CHECK
+  if (st_STACKPOINTER >= st_STACKSIZE) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In st_StackPush: ST-Stack Overflow!\n");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  st_STACK[st_STACKPOINTER++] = Entry;
+}
+
+static __inline__ void st_StackPop(void)
+{
+  --st_STACKPOINTER;
+}
+
+static __inline__ POINTER st_StackPopResult(void)
+{
+  return st_STACK[--st_STACKPOINTER];
+}
+
+static __inline__ void st_StackNPop(int N)
+{
+  st_STACKPOINTER -= N;
+}
+
+static __inline__ POINTER st_StackTop(void)
+{
+  return st_STACK[st_STACKPOINTER - 1];
+}
+
+static __inline__ POINTER st_StackNthTop(int N)
+{
+  return st_STACK[st_STACKPOINTER - (1 + N)];
+}
+
+static __inline__ void st_StackRplacTop(POINTER Entry)
+{
+  st_STACK[st_STACKPOINTER - 1] = Entry;
+}
+
+static __inline__ void st_StackRplacNthTop(int N, POINTER Entry)
+{
+  st_STACK[st_STACKPOINTER - (1 + N)] = Entry;
+}
+
+static __inline__ void st_StackRplacNth(int N, POINTER Entry)
+{
+  st_STACK[N] = Entry;
+}
+
+static __inline__ int st_StackBottom(void)
+{
+  return st_STACKPOINTER;
+}
+
+static __inline__ void st_StackSetBottom(int Pointer)
+{
+  st_STACKPOINTER = Pointer;
+}
+
+static __inline__ BOOL st_StackEmpty(int Pointer)
+{
+  return st_STACKPOINTER == Pointer;
+}
+
+
+/**************************************************************/
+/* Functions for Creation and Deletion of an st_INDEX         */
+/**************************************************************/
+
+st_INDEX st_IndexCreate(void); 
+void     st_IndexDelete(st_INDEX);
+
+/**************************************************************/
+/* Add and Remove Entries to an st_INDEX                      */
+/**************************************************************/
+
+void     st_EntryCreate(st_INDEX, POINTER, TERM, const CONTEXT);
+BOOL     st_EntryDelete(st_INDEX, POINTER, TERM, const CONTEXT);
+
+/**************************************************************/
+/* Functions for Retrieval in the Index                       */
+/**************************************************************/
+
+LIST     st_GetUnifier(CONTEXT, st_INDEX, CONTEXT, TERM);
+LIST     st_GetGen(CONTEXT, st_INDEX, TERM);
+LIST     st_GetGenPreTest(CONTEXT, st_INDEX, TERM);
+LIST     st_GetInstance(CONTEXT, st_INDEX, TERM);
+LIST     st_GetInstancePreTest(CONTEXT, st_INDEX, TERM);
+
+void     st_CancelExistRetrieval(void);
+
+POINTER  st_ExistUnifier(CONTEXT, st_INDEX, CONTEXT, TERM);
+POINTER  st_ExistGen(CONTEXT, st_INDEX, TERM);
+POINTER  st_ExistGenPreTest(CONTEXT, st_INDEX, TERM);
+POINTER  st_ExistInstance(CONTEXT, st_INDEX, TERM);
+POINTER  st_ExistInstancePreTest(CONTEXT, st_INDEX, TERM);
+
+POINTER  st_NextCandidate(void);
+
+/**************************************************************/
+/* Function for Output                                        */
+/**************************************************************/
+
+void     st_Print(st_INDEX, void (*)(POINTER));
+
+#endif
diff --git a/test/spass/stack.c b/test/spass/stack.c
new file mode 100644
index 0000000000000000000000000000000000000000..4d46314d774ed1d4c3988f4ce2632f7c7ae2563a
--- /dev/null
+++ b/test/spass/stack.c
@@ -0,0 +1,55 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *              GLOBAL SYSTEM STACK                       * */
+/* *                                                        * */
+/* *  $Module:      STACK                                   * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1999, 2001 MPI fuer Informatik          * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "stack.h"
+
+
+/**************************************************************/
+/* Global Variables                                           */
+/**************************************************************/
+
+STACK stack_STACK;
+NAT   stack_POINTER;
diff --git a/test/spass/stack.h b/test/spass/stack.h
new file mode 100644
index 0000000000000000000000000000000000000000..4572b34b626b4d4a64663ae52063475e24aaa427
--- /dev/null
+++ b/test/spass/stack.h
@@ -0,0 +1,155 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *              GLOBAL SYSTEM STACK                       * */
+/* *                                                        * */
+/* *  $Module:      STACK                                   * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1998, 1999, 2001                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _STACK_
+#define _STACK_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "misc.h"
+
+/**************************************************************/
+/* More basic types and macros                                */
+/**************************************************************/
+
+
+#define stack_SIZE 10000
+
+typedef POINTER STACK[stack_SIZE];
+
+
+/**************************************************************/
+/* Global Variables                                           */
+/**************************************************************/
+
+extern STACK stack_STACK;
+extern NAT   stack_POINTER;
+
+
+/**************************************************************/
+/* Inline Functions                                           */
+/**************************************************************/
+
+static __inline__ void stack_Init(void)
+{
+  stack_POINTER = 0;
+}
+
+static __inline__ void stack_Push(POINTER Entry)
+{
+#ifdef CHECK
+  if (stack_POINTER >= stack_SIZE) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In stack_Push: Stack Overflow.");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  stack_STACK[stack_POINTER++]= Entry;
+}
+
+static __inline__ int stack_Pop(void)
+{
+  return --stack_POINTER;
+}
+
+static __inline__ POINTER stack_PopResult(void)
+{
+  return stack_STACK[--stack_POINTER];
+}
+
+static __inline__ void stack_NPop(NAT N)
+{
+  stack_POINTER -= N;
+}
+
+static __inline__ POINTER stack_Top(void)
+{
+  return stack_STACK[stack_POINTER-1];
+}
+
+static __inline__ POINTER stack_NthTop(NAT N)
+{
+  return stack_STACK[stack_POINTER-(1+N)];
+}
+
+static __inline__ void stack_RplacTop(POINTER Entry)
+{
+  stack_STACK[stack_POINTER-1] = Entry;
+}
+
+static __inline__ void stack_RplacNthTop(NAT N, POINTER Entry)
+{
+  stack_STACK[stack_POINTER-(1+N)] = Entry;
+}
+
+static __inline__ void stack_RplacNth(NAT N, POINTER Entry)
+{
+  stack_STACK[N] = Entry;
+}
+
+static __inline__ NAT stack_Bottom(void)
+{
+  return stack_POINTER;
+}
+
+static __inline__ void stack_SetBottom(NAT Ptr)
+{
+  stack_POINTER = Ptr;
+}
+
+static __inline__ BOOL stack_Empty(NAT Ptr)
+{
+  return stack_POINTER == Ptr;
+}
+
+
+#endif
+
+
diff --git a/test/spass/strings.c b/test/spass/strings.c
new file mode 100644
index 0000000000000000000000000000000000000000..bd0b2ed1fe61f982e9c90f27660e503afba7722e
--- /dev/null
+++ b/test/spass/strings.c
@@ -0,0 +1,325 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                STRING HANDLING                         * */
+/* *                                                        * */
+/* *  $Module:   STRINGS                                    * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1999, 2000, 2001 MPI fuer Informatik    * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 35442 $                                        * */
+/* $State$                                            * */
+/* $Date: 2007-03-28 17:24:40 -0700 (Wed, 28 Mar 2007) $                             * */
+/* $Author: jeffc $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include <ctype.h>
+#include "stringsx.h"
+#include "list.h"
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+
+
+BOOL string_StringIsNumber(const char* String)
+/**************************************************************
+  INPUT:   A string.
+  RETURNS: TRUE iff the string solely consists of number characters.
+***************************************************************/
+{
+  int i;
+  
+  if (String == NULL || String[0] == '\0')
+    return FALSE;
+  
+  i = 0;
+
+  while (String[i] != '\0')
+    if (String[i] >= '0' && String[i] <= '9')
+      i++;
+    else
+      return FALSE;
+
+  return TRUE;  
+}
+
+
+char* string_StringCopy(const char* String)
+/**************************************************************
+  INPUT:   A string.
+  RETURNS: A copy of the string.
+  EFFECT:  The memory for the copy is allocated by the memory module.
+***************************************************************/
+{
+  char *copy;
+
+  copy = (char *) memory_Malloc(strlen(String)+1);
+  strcpy(copy, String);
+  return copy;
+}
+
+
+void  string_StringFree(char* String)
+/**************************************************************
+  INPUT:   A string.
+  RETURNS: Nothing.
+  EFFECT:  Frees the memory used by the string.
+***************************************************************/
+{
+  memory_Free(String, strlen(String)+1);
+}
+
+
+char* string_IntToString(int Number)
+/**************************************************************
+  INPUT:   An integer number.
+  RETURNS: The number as a string.
+  EFFECT:  Memory is allocated for the string.
+***************************************************************/
+{
+  char* result;
+  NAT   size = 1;
+
+  if (Number > 9) {
+    size = (NAT)log10((double) Number) + 1;
+  } else if (Number < 0) {
+    size = (NAT)log10((double) abs(Number)) + 2; /* including '-' */
+  }
+  size++; /* for '\0' */
+
+  result = (char *) memory_Malloc(sizeof(char) * size);
+  sprintf(result, "%d", Number);
+  return result;
+}
+
+
+BOOL string_StringToInt(const char* String, BOOL PrintError, int* Result)
+/**************************************************************
+  INPUT:   A string that should represent a decimal number in the
+           format of the library function strtol, a boolean flag
+	   concerning the printing of error messages and an pointer
+	   to an integer that is used as a return value.
+  RETURNS: TRUE, if the string could be converted successfully, else FALSE.
+  EFFECT:  This function converts the string a number of type 'int'.
+	   If the string was converted successfully, the value of the
+	   number is stored in <*Result> and the function returns TRUE.
+           If the number is too big (> INT_MAX), too small (< INT_MIN)
+	   or the string couldn't be converted completely, <*Result> is
+	   set to 0.
+	   If <PrintError> is TRUE, additionally an error message is written
+           to stderr and the program exits.
+***************************************************************/
+{
+  long number;
+  char *end;
+
+  end    = (char*)0x1;   /* Has to be != NULL, so we take address 1 */
+  number = strtol(String, &end, 10);
+  /* Now <number> is LONG_MAX or LONG_MIN if the string represents a value */
+  /* out of range. The variable <end> is set to the first non-converted    */
+  /* character, e.g. if the string can be converted completely, <end> points */
+  /* to the terminating '\0' character. */
+  if (number >= INT_MIN && number <= INT_MAX && *end == '\0') {
+    /* Number was converted successfully */
+    *Result = (int)number;
+    return TRUE;
+  } else {
+    /* Number is too large or buffer can't be converted completely */
+    *Result = 0;
+    if (PrintError) {
+      misc_StartUserErrorReport();
+      misc_UserErrorReport("\nString isn't a number or number to large: %s\n",
+			   String);
+      misc_FinishUserErrorReport();
+    }
+    return FALSE;
+  }
+}
+
+
+char* string_Conc(const char* s1, const char* s2)
+/**************************************************************
+  INPUT:   Two strings.
+  RETURNS: A new string s1.s2
+  EFFECTS: Memory is allocated for the new string.
+**************************************************************/
+{ 
+  char* dst;
+
+  dst = memory_Malloc(strlen(s1) + strlen(s2) + 1);
+  strcpy(dst, s1);
+  return strcat(dst,s2);
+}
+
+
+char* string_Nconc(char* s1, char* s2)
+/**************************************************************
+ INPUT:   Two strings.
+ RETURNS: A new string s1.s2.
+ EFFECTS: s1,s2 are deleted, memory for the new string is
+          allocated.
+ CAUTION: Both strings must have been allocated by the memory module!
+**************************************************************/
+{ 
+  char* dst;
+
+  dst = memory_Malloc(strlen(s1) + strlen(s2) + 1);
+  strcpy(dst, s1);
+  dst = strcat(dst, s2);
+  
+  string_StringFree(s1);
+  string_StringFree(s2);
+
+  return dst;
+}
+
+
+char* string_EmptyString(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: The empty string.
+  EFFECT:  Memory is allocated for the returned string.
+**************************************************************/
+{
+  char* s ;
+
+  s = memory_Malloc(1);
+  s[0] = '\0';
+  return s;
+}
+
+
+char* string_Prefix(const char* s, int i)
+/**************************************************************
+  INPUT:   A string and a string length.
+  RETURNS: The prefix of <s> of length <i>.
+  EFFECT:  Memory is allocated for the returned string.
+**************************************************************/
+{
+  char* dst;
+
+  dst = memory_Malloc(i + 1);
+  strncpy(dst, s, i);
+  dst[i] = '\0';
+  return dst;
+}
+
+
+char* string_Suffix(const char* s, int i)
+/**************************************************************
+  INPUT:   A string and a string length.
+  RETURNS: The string that results from cutting the first
+           <i> characters from string <s>.
+           Returns the empty string if <i> >= length(s).
+  EFFECT:  Memory is allocated for the returned string.
+**************************************************************/
+{
+  int  l;
+  char *dst;
+  
+  l = strlen(s);
+  if (i >= l)
+    return string_EmptyString();
+
+  dst = memory_Malloc(l - i + 1);
+  strcpy(dst, s+i);
+  return dst;
+}
+
+
+char** string_Tokens(char* String, int* ArraySize)
+/**************************************************************
+  INPUT:   A string <String>.
+  RETURNS: The function returns an array of white space separated
+           substrings from <String>. <ArraySize> is set to the
+	   actual size of the returned array.
+	   The array size is the number of substrings + 2, since
+	   the first entry is the program name and the last entry
+	   is NULL.
+	   This is done so to create an array similar to the
+	   "argv" argument of the main() function.
+  EFFECT:  This function breaks the string into several substrings
+	   that don't contain any whitespace characters.
+	   The argument string is modified temporarily within this
+	   function, but it's restored at the end.
+***************************************************************/
+{
+  char *LastNonSpace, *Scan, Help, **Array;
+  LIST Substrings;
+  NAT  i;
+
+#ifdef CHECK
+  if (String == NULL) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In string_Tokens: String is NULL pointer.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Substrings = list_Nil();
+  Scan = String + strlen(String) - 1;
+  while (Scan >= String) {
+    while (Scan >= String && isspace((int)*Scan))
+      Scan--;
+
+    if (Scan >= String) {
+      LastNonSpace = Scan;
+      
+      do {
+	Scan--;
+      } while (Scan >= String && !isspace((int)*Scan));
+      
+      Help = *(LastNonSpace + 1);
+      *(LastNonSpace + 1) = '\0';
+      Substrings = list_Cons(string_StringCopy(Scan+1), Substrings);
+      *(LastNonSpace + 1) = Help;
+    }
+  }
+
+  *ArraySize = list_Length(Substrings) + 2;
+  Array = memory_Malloc(sizeof(char*) * *ArraySize);
+  Array[0] = string_StringCopy("SPASS");
+  for (i = 1; !list_Empty(Substrings); Substrings = list_Pop(Substrings), i++)
+    Array[i] = list_Car(Substrings);
+  Array[i] = NULL;
+  (*ArraySize)--;
+
+  return Array;
+}
diff --git a/test/spass/stringsx.h b/test/spass/stringsx.h
new file mode 100644
index 0000000000000000000000000000000000000000..7209b4b51fa943ae01fc0b52917b16d4debc57a7
--- /dev/null
+++ b/test/spass/stringsx.h
@@ -0,0 +1,88 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                STRING HANDLING                         * */
+/* *                                                        * */
+/* *  $Module:   STRINGS                                    * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1999, 2000, 2001 MPI fuer Informatik    * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 35442 $                                        * */
+/* $State$                                            * */
+/* $Date: 2007-03-28 17:24:40 -0700 (Wed, 28 Mar 2007) $                             * */
+/* $Author: jeffc $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _STRINGS_
+#define _STRINGS_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include <math.h>
+#include "memory.h"
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static __inline__ BOOL string_Equal(const char* S1, const char* S2)
+{
+  return strcmp(S1, S2) == 0;
+}
+
+
+BOOL   string_StringIsNumber(const char*);
+char*  string_StringCopy(const char*);
+void   string_StringFree(char*);
+char*  string_IntToString(int);
+BOOL   string_StringToInt(const char*, BOOL, int*);
+char*  string_Conc(const char*, const char*);
+char*  string_Nconc(char*, char*);
+char*  string_EmptyString(void);
+char*  string_Prefix(const char*, int);
+char*  string_Suffix(const char*, int);
+char** string_Tokens(char*, int*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/test/spass/subst.c b/test/spass/subst.c
new file mode 100644
index 0000000000000000000000000000000000000000..a7d5ea3509a77542a5319c855f06f2076d578180
--- /dev/null
+++ b/test/spass/subst.c
@@ -0,0 +1,647 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                     SUBSTITUTION                       * */
+/* *                                                        * */
+/* *  $Module:      SUBSTITUTION                            * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "subst.h"
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  SUBSTITUTION CREATION AND DELETION                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+SUBST subst_Add(SYMBOL Symbol, TERM Codomain, SUBST Subst)
+{
+  SUBST Result;
+
+  Result           = subst_Get();
+  Result->next     = Subst;
+  Result->dom      = Symbol;
+  Result->codomain = Codomain;
+
+  return Result;
+}
+
+
+void subst_Delete(SUBST Subst)
+{
+  SUBST Next;
+
+  while (subst_Exist(Subst)) {
+    Next = subst_Next(Subst);
+
+    if (subst_Cod(Subst))
+      term_Delete(subst_Cod(Subst));
+
+    subst_FreeOneNode(Subst);
+    Subst = Next;
+  }
+}
+
+void subst_Free(SUBST Subst)
+{
+  SUBST Next;
+
+  while (subst_Exist(Subst)) {
+    Next = subst_Next(Subst);
+    subst_FreeOneNode(Subst);
+    Subst = Next;
+  }
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  FUNCTIONS ON SUBSTITUTIONS                            * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+TERM subst_Term(SYMBOL Symbol, SUBST Subst)
+{
+  for (; subst_Exist(Subst); Subst = subst_Next(Subst))
+    if (symbol_Equal(Symbol,subst_Dom(Subst)))
+      return subst_Cod(Subst);
+  return (TERM)NULL;
+}
+
+
+static TERM subst_ApplyIntern(SUBST Subst, TERM Term)
+{
+  TERM   RplacTerm;
+  LIST   Arglist;
+  SYMBOL Top;
+
+  Top = term_TopSymbol(Term);
+
+  if (symbol_IsVariable(Top) && (RplacTerm = subst_Term(Top,Subst))) {
+    Arglist = term_CopyTermList(term_ArgumentList(RplacTerm));
+    term_RplacTop(Term, term_TopSymbol(RplacTerm));
+    term_DeleteTermList(term_ArgumentList(Term));
+    term_RplacArgumentList(Term, Arglist);
+  } else {
+    for (Arglist = term_ArgumentList(Term);
+	 !list_Empty(Arglist);
+	 Arglist = list_Cdr(Arglist))
+      subst_ApplyIntern(Subst, list_Car(Arglist));
+  }     
+
+  return Term;
+}
+
+TERM subst_Apply(SUBST Subst, TERM Term)
+{
+  if (subst_Empty(Subst))
+    return Term;
+
+  return subst_ApplyIntern(Subst, Term);
+}
+
+
+SUBST subst_Merge(SUBST Source, SUBST Drain)
+{
+  SUBST Scan;
+  BOOL  Changed;
+  
+  for (; subst_Exist(Source); Source = subst_Next(Source)) {
+    
+    /* Apply current assignment of Source to all  */
+    /* assignments of Drain. If the current ass.  */
+    /* cannot be applied to any codomain in Drain */
+    /* the current assignment is added to Drain.  */
+    
+    Changed = FALSE;
+
+    for (Scan = Drain;
+	 subst_Exist(Scan);
+	 Scan = subst_Next(Scan))
+      if (term_SubstituteVariable(Source->dom,
+				   Source->codomain,
+				   &(Scan->codomain)))
+	Changed = TRUE;
+
+    if (!Changed)
+      Drain = subst_Add(Source->dom, 
+			term_Copy(Source->codomain),
+			Drain);
+  }
+
+  return Drain;
+}
+
+SUBST subst_Compose(SUBST Outer, SUBST Inner)
+/**************************************************************
+  INPUT:   Two substitutions.
+  RETURNS: The substitution corresponding to the composition of
+           <Outer> and <Inner>.
+  EFFECT:  <Outer> is destructively applied to the codomain of <Inner>
+           <Inner> is destructively extended
+***************************************************************/
+{
+  SUBST Scan1,Scan2,New;
+
+  New = subst_Nil();
+  
+  for (Scan1=Outer; subst_Exist(Scan1); Scan1 = subst_Next(Scan1)) {    
+    for (Scan2 = Inner;subst_Exist(Scan2);Scan2 = subst_Next(Scan2))
+      term_SubstituteVariable(subst_Dom(Scan1),subst_Cod(Scan1),&(Scan2->codomain));
+    if (!subst_BindVar(subst_Dom(Scan1),Inner))
+      New = subst_Add(subst_Dom(Scan1), term_Copy(subst_Cod(Scan1)),New);
+  }
+  return subst_NUnion(Inner,New);
+}
+
+BOOL subst_BindVar(SYMBOL Var, SUBST Subst)
+/**************************************************************
+  INPUT:   A variable symbol and a substitution.
+  RETURNS: TRUE iff <Var> is contained in the domain of <Subst>
+***************************************************************/
+{
+  SUBST Scan;
+
+  for (Scan=Subst; subst_Exist(Scan); Scan = subst_Next(Scan))
+    if (symbol_Equal(subst_Dom(Scan),Var))
+      return TRUE;
+
+  return FALSE;
+}
+
+
+
+SUBST subst_Copy(SUBST Subst)
+{
+  SUBST Copy, Result;
+
+  for (Result = subst_Nil(),
+       Copy   = subst_Nil();
+       subst_Exist(Subst);
+       Subst = subst_Next(Subst))
+    if (subst_Exist(Result)) {
+      subst_SetNext(Copy, subst_Add(subst_Dom(Subst),
+				    term_Copy(subst_Cod(Subst)),
+				    subst_Nil()));
+      Copy = subst_Next(Copy);
+    } else {
+      Result = subst_Add(subst_Dom(Subst),
+			 term_Copy(subst_Cod(Subst)),
+			 subst_Nil());
+      Copy = Result;
+    }
+
+  return Result;
+}
+
+
+BOOL subst_MatchTops(const CONTEXT Context, SUBST Subst)
+{
+  for ( ; subst_Exist(Subst); Subst = subst_Next(Subst))
+    if (cont_ContextBindingTerm(Context, subst_Dom(Subst)) &&
+	term_EqualTopSymbols(cont_ContextBindingTerm(Context, subst_Dom(Subst)),
+			     subst_Cod(Subst)))
+      return TRUE;
+  return FALSE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  UNIFICATION TEST                                      * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL subst_Unify(CONTEXT IndexContext, SUBST Subst)
+/*********************************************************
+  INPUT:
+  RETURNS:
+  CAUTION: 'Subst' IS ASSUMED TO BE NON-EMPTY.
+**********************************************************/
+{
+  while (subst_Exist(Subst)) {
+    if (!cont_VarIsBound(IndexContext, subst_Dom(Subst))) {
+      if (unify_OccurCheck(IndexContext, subst_Dom(Subst), IndexContext, subst_Cod(Subst)))
+	return FALSE;
+      else
+	cont_CreateBinding(IndexContext, subst_Dom(Subst), IndexContext, subst_Cod(Subst));
+    } else if (!unify_UnifyAllOC(IndexContext,
+				 IndexContext,
+				 subst_Cod(Subst),
+				 cont_ContextBindingContext(IndexContext,
+							       subst_Dom(Subst)),
+				 cont_ContextBindingTerm(IndexContext,
+							    subst_Dom(Subst))))
+      return FALSE;
+
+    Subst = subst_Next(Subst);
+  }
+
+  return TRUE;
+}
+
+BOOL subst_IsShallow(SUBST Subst) {
+/**********************************************************
+  INPUT:   A unifier
+  RETURNS: TRUE, if the unifier is valid :
+           a variable or a ground term  or a function with only
+           variables or ground terms as arguments.
+***********************************************************/
+    SUBST SubstScan;
+    for (SubstScan = Subst; SubstScan != subst_Nil();
+	 SubstScan = subst_Next(SubstScan)) {
+	TERM Codomain = subst_Cod(SubstScan);
+	if ((!term_IsVariable(Codomain)) 
+	    && (!term_IsGround(Codomain))) {
+	  LIST Scan ;
+	  for (Scan = term_ArgumentList(Codomain); Scan != list_Nil(); 
+	       Scan = list_Cdr(Scan)) {
+	    if ((!term_IsVariable(list_Car(Scan))
+		 && (!term_IsGround(list_Car(Scan)))))
+	      return FALSE;
+	  }
+	}
+    }
+    return TRUE;
+}
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  GENERALIZATION TEST                                   * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL subst_Match(const CONTEXT Context, SUBST Subst)
+/*********************************************************
+  INPUT:
+  RETURNS:
+  CAUTION: 'Subst' IS ASSUMED TO BE NON-EMPTY.
+**********************************************************/
+{
+  while (subst_Exist(Subst)) {
+    if (!cont_VarIsBound(Context, subst_Dom(Subst)) ||
+	!unify_Match(Context,
+		     subst_Cod(Subst),
+		     cont_ContextBindingTerm(Context, subst_Dom(Subst))))
+      return FALSE;
+    
+    Subst = subst_Next(Subst);
+  }
+
+  return TRUE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  INSTANCE TEST                                         * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL subst_MatchReverse(const CONTEXT IndexContext, SUBST Subst)
+/*********************************************************
+  INPUT:
+  RETURNS:
+  CAUTION: 'Subst' IS ASSUMED TO BE NON-EMPTY.
+**********************************************************/
+{
+  while (subst_Exist(Subst)) {
+
+    if (!cont_VarIsBound(IndexContext, subst_Dom(Subst))) {
+      if (symbol_IsIndexVariable(subst_Dom(Subst)))
+	cont_CreateBinding(IndexContext,
+			      subst_Dom(Subst),
+			      cont_InstanceContext(),
+			      subst_Cod(Subst));
+      else
+	return FALSE;
+    }
+    else if (!unify_MatchReverse(IndexContext,
+				 subst_Cod(Subst),
+				 cont_ContextBindingContext(IndexContext, subst_Dom(Subst)),
+				 cont_ContextBindingTerm(IndexContext, subst_Dom(Subst))))
+      return FALSE;
+
+    Subst = subst_Next(Subst);
+  }
+
+  return TRUE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  VARIATION TEST                                        * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL subst_Variation(const CONTEXT Context, SUBST Subst)
+/*********************************************************
+  INPUT:
+  RETURNS:
+  CAUTION: 'Subst' IS ASSUMED TO BE NON-EMPTY.
+**********************************************************/
+{
+  while (subst_Exist(Subst)) {
+
+    if (!cont_VarIsBound(Context, subst_Dom(Subst)) ||
+	!unify_Variation(Context,
+			 subst_Cod(Subst),
+			 cont_ContextBindingTerm(Context, subst_Dom(Subst))))
+      return FALSE;
+    
+    Subst = subst_Next(Subst);
+  }
+
+  return TRUE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  COMMON GENERALIZATIONS                                * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+SUBST subst_ComGen(const CONTEXT Context, SUBST Subst, SUBST* SubstOld,
+		   SUBST* SubstNew)
+/*********************************************************
+  INPUT:
+  RETURNS:
+  CAUTION: 'Subst' IS ASSUMED TO BE NON-EMPTY.
+**********************************************************/
+{
+  SUBST Result;
+  
+  Result = *SubstOld = *SubstNew = NULL;
+  
+  do {
+    
+    if (!cont_VarIsBound(Context, subst_Dom(Subst)))
+      *SubstOld=subst_Add(subst_Dom(Subst), term_Copy(subst_Cod(Subst)), *SubstOld);
+
+    else if (term_Equal(cont_ContextBindingTerm(Context, subst_Dom(Subst)),
+			subst_Cod(Subst)))
+      Result = subst_Add(subst_Dom(Subst), term_Copy(subst_Cod(Subst)), Result);
+
+    else
+      if (!symbol_Equal(term_TopSymbol(cont_ContextBindingTerm(Context,
+								  subst_Dom(Subst))),
+			term_TopSymbol(subst_Cod(Subst)))) {
+
+      *SubstOld=subst_Add(subst_Dom(Subst),
+			  term_Copy(subst_Cod(Subst)),
+			  *SubstOld);
+      *SubstNew=subst_Add(subst_Dom(Subst),
+			  term_Copy(cont_ContextBindingTerm(Context,
+							       subst_Dom(Subst))),
+			  *SubstNew);
+
+    } else
+      Result = subst_Add(subst_Dom(Subst),
+			 unify_ComGenLinear(Context,
+					    SubstNew,
+					    cont_ContextBindingTerm(Context,
+								       subst_Dom(Subst)),
+					    SubstOld,
+					    subst_Cod(Subst)),
+			 Result);
+
+    cont_CloseBinding(Context, subst_Dom(Subst));
+
+    Subst = subst_Next(Subst);
+  } while (subst_Exist(Subst));
+
+  return Result;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  CLOSE BINDINGS                                        * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+void subst_CloseVariables(const CONTEXT Context, SUBST Subst)
+{
+  for (; subst_Exist(Subst); Subst = subst_Next(Subst))
+    cont_CloseBinding(Context, subst_Dom(Subst));
+}
+
+
+SUBST subst_CloseOpenVariables(SUBST Result)
+{
+  while (cont_LastBinding()) {
+    if (cont_LastIsBound())
+      Result = subst_Add(cont_LastBindingSymbol(),
+			 term_Copy(cont_LastBindingTerm()),
+			 Result);
+    cont_BackTrackLastBinding();
+  }
+
+  return Result;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *							    * */
+/* *  EXTRACT UNIFIER                                       * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+void subst_ExtractUnifier(const CONTEXT CL,
+			  SUBST* LeftSubst,
+			  const CONTEXT CR,
+			  SUBST* RightSubst)
+/*********************************************************
+  INPUT:   'LeftSubst', 'RightSubst' for the unifier,
+           renaming the codomain variables starts at
+           'MinimumCoVariable' excl., number of
+           renamings are ADDED to 'Bindings'.
+  RETURNS: Nothing.
+  SUMMARY: Extracts the unifier into two substitutions
+           with renamed variables in the codomain.
+  CAUTION: DOES NOT RESET THE BINDINGS, CREATES EVEN
+           MORE BINDINGS BECAUSE OF RENAMING.
+**********************************************************/
+{
+  CONTEXT Scan;
+
+  *LeftSubst  = subst_Nil();
+  *RightSubst = subst_Nil();
+
+  Scan        = cont_LastBinding();
+
+  while (Scan) {
+    if (cont_IsInContext(CL,
+			    cont_BindingSymbol(Scan),
+			    Scan))
+      *LeftSubst = subst_Add(cont_BindingSymbol(Scan),
+			     cont_CopyAndApplyBindings(cont_BindingContext(Scan),
+							  cont_BindingTerm(Scan)),
+			     *LeftSubst);
+    else if (cont_IsInContext(CR,
+				 cont_BindingSymbol(Scan),
+				 Scan))
+      *RightSubst = subst_Add(cont_BindingSymbol(Scan),
+			      cont_CopyAndApplyBindings(cont_BindingContext(Scan),
+							   cont_BindingTerm(Scan)),
+			      *RightSubst);
+    
+    Scan = cont_BindingLink(Scan);
+  }
+}
+
+
+void subst_ExtractUnifierCom(const CONTEXT Context, SUBST* Subst)
+/*********************************************************
+  INPUT:  'LeftSubst', 'RightSubst' for the unifier,
+          renaming the codomain variables starts at
+          'MinimumCoVariable' excl., number of
+          renamings are ADDED to 'Bindings'.
+ RETURNS: Nothing.
+ SUMMARY: Extracts the unifier into two substitutions
+          with renamed variables in the codomain.
+ CAUTION: DOES NOT RESET THE BINDINGS, CREATES EVEN
+          MORE BINDINGS BECAUSE OF RENAMING.
+**********************************************************/
+{
+  CONTEXT Scan;
+
+  *Subst = subst_Nil();
+
+  Scan   = cont_LastBinding();
+
+  while (Scan) {
+    *Subst =
+      subst_Add(cont_BindingSymbol(Scan),
+		cont_CopyAndApplyBindingsCom(Context, cont_BindingTerm(Scan)),
+		*Subst);
+
+    Scan = cont_BindingLink(Scan);
+  }
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *							    * */
+/* *  EXTRACT MATCHER                                       * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+SUBST subst_ExtractMatcher(void)
+/*********************************************************
+  INPUT:   None.
+  RETURNS: The matcher.
+  SUMMARY: Extracts the matcher without renaming.
+  CAUTION: DOES NOT RESET THE BINDINGS, DOES NOT COPY
+           THE CODOMAINS.
+**********************************************************/
+{
+  CONTEXT     Scan;
+  SUBST Result;
+
+  for (Scan = cont_LastBinding(), Result = subst_Nil();
+       Scan;
+       Scan = cont_BindingLink(Scan))
+    Result = subst_Add(cont_BindingSymbol(Scan),
+		       cont_BindingTerm(Scan),
+		       Result);
+
+  return Result;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  OUTPUT                                                * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+void subst_Print(SUBST Subst)
+{
+  fputs("{ ", stdout);
+  for (; subst_Exist(Subst); Subst = subst_Next(Subst)) {
+    symbol_Print(subst_Dom(Subst));
+    if (subst_Cod(Subst)) {
+      fputs(" -> ", stdout);
+      term_PrintPrefix(subst_Cod(Subst));
+    }
+    if (subst_Next(Subst))
+      fputs("; ", stdout);
+  }
+  fputs(" }", stdout);
+}
+
diff --git a/test/spass/subst.h b/test/spass/subst.h
new file mode 100644
index 0000000000000000000000000000000000000000..db26197c6bad98b859c369913e06be3bca679920
--- /dev/null
+++ b/test/spass/subst.h
@@ -0,0 +1,219 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                     SUBSTITUTION                       * */
+/* *                                                        * */
+/* *  $Module:      SUBSTITUTION                            * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2001            * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _SUBST_
+#define _SUBST_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "term.h"
+#include "symbol.h"
+#include "list.h"
+
+/**************************************************************/
+/* Data Structures                                            */
+/**************************************************************/
+
+typedef struct subst {
+  struct subst *next;
+  SYMBOL dom;
+  TERM   codomain;
+} SUBST_NODE, *SUBST;
+
+
+static __inline__ SUBST subst_Get(void)
+{
+  return (SUBST) memory_Malloc(sizeof(SUBST_NODE));
+}
+
+static __inline__ void subst_FreeOneNode(SUBST SL)
+{
+  memory_Free(SL, sizeof(SUBST_NODE));
+}
+
+/**************************************************************/
+/* Include 'unify.h' after SUBST declaration.                 */
+/**************************************************************/
+
+#include "unify.h"
+
+/**************************************************************/
+/* Functions on Substitutions                                 */
+/**************************************************************/
+
+static __inline__ SUBST subst_Nil(void)
+{
+  return (SUBST)NULL;
+}
+
+static __inline__ BOOL subst_Exist(SUBST S)
+{
+  return S != subst_Nil();
+}
+
+static __inline__ BOOL subst_Empty(SUBST S)
+{
+  return S == subst_Nil();
+}
+
+static __inline__ SUBST subst_Next(SUBST S)
+{
+  return S->next;
+}
+
+static __inline__ void subst_SetNext(SUBST S, SUBST N)
+{
+  S->next = N;
+}
+
+static __inline__ SYMBOL subst_Dom(SUBST S)
+{
+  return S->dom;
+}
+
+static __inline__ TERM subst_Cod(SUBST S)
+{
+  return S->codomain;
+}
+
+static __inline__ SUBST subst_NUnion(SUBST S1,SUBST S2)
+{
+  SUBST Result;
+
+  if (S1 == (SUBST)NULL)  
+    return S2;        
+
+  if (S2 == (SUBST)NULL) 
+    return S1;
+
+  Result = S1;
+
+  for (; S1->next != (SUBST)NULL; S1 = S1->next);
+            
+  S1->next = S2;
+
+  return Result; 
+}
+
+
+/**************************************************************/
+/* Functions for Creation and Deletion                        */
+/**************************************************************/
+
+SUBST subst_Add(SYMBOL, TERM, SUBST);
+void  subst_Delete(SUBST);
+void  subst_Free(SUBST);
+
+/**************************************************************/
+/* Functions for Applying and Copying                         */
+/**************************************************************/
+
+TERM  subst_Term(SYMBOL, SUBST);
+TERM  subst_Apply(SUBST, TERM);
+SUBST subst_Merge(SUBST, SUBST);
+SUBST subst_Compose(SUBST, SUBST);
+SUBST subst_Copy(SUBST);
+BOOL  subst_MatchTops(const CONTEXT, SUBST);
+BOOL  subst_BindVar(SYMBOL,SUBST);
+
+/**************************************************************/
+/* Functions for Search of Unifiers                           */
+/**************************************************************/
+
+BOOL subst_Unify(CONTEXT, SUBST);
+BOOL subst_IsShallow(SUBST);
+
+/**************************************************************/
+/* Functions for Search of Generalizations                    */
+/**************************************************************/
+
+BOOL  subst_Match(const CONTEXT, SUBST);
+
+/**************************************************************/
+/* Functions for Search of Instances                          */
+/**************************************************************/
+
+BOOL  subst_MatchReverse(const CONTEXT, SUBST);
+
+/**************************************************************/
+/* Functions for Search of Variations                         */
+/**************************************************************/
+
+BOOL  subst_Variation(const CONTEXT, SUBST);
+
+/**************************************************************/
+/* Functions for Computation of MSCGs                         */
+/**************************************************************/
+
+SUBST subst_ComGen(const CONTEXT, SUBST, SUBST*, SUBST*);
+
+/**************************************************************/
+/* Functions for Closing Bindings                             */
+/**************************************************************/
+
+void  subst_CloseVariables(const CONTEXT, SUBST);
+SUBST subst_CloseOpenVariables(SUBST);
+
+/**************************************************************/
+/* Functions for Extracting Substitutions from Bindings       */
+/**************************************************************/
+
+void      subst_ExtractUnifier(const CONTEXT, SUBST*, const CONTEXT, SUBST*);
+void      subst_ExtractUnifierCom(const CONTEXT, SUBST*);
+SUBST     subst_ExtractMatcher(void);
+
+/**************************************************************/
+/* Functions for Debugging                                    */
+/**************************************************************/
+
+void  subst_Print(SUBST);
+
+#endif
+
+
diff --git a/test/spass/subsumption.c b/test/spass/subsumption.c
new file mode 100644
index 0000000000000000000000000000000000000000..d312cbf8875b76679eba08bbf983b9be18e09d5b
--- /dev/null
+++ b/test/spass/subsumption.c
@@ -0,0 +1,2041 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                     SUBSUMPTION                        * */
+/* *                                                        * */
+/* *  $Module:   SUBSUMPTION                                * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#include "subsumption.h"
+
+static NAT multvec_i[subs__MAXLITS];
+static NAT multvec_j[subs__MAXLITS];
+static NAT stamp;
+
+static BOOL subs_InternIdc(CLAUSE, int, CLAUSE);
+static BOOL subs_InternIdcEq(CLAUSE, int, CLAUSE);
+static BOOL subs_InternIdcEqExcept(CLAUSE, int, CLAUSE, int);
+static BOOL subs_InternIdcRes(CLAUSE, int, int, int);
+
+/* The following functions are currently unused */
+BOOL subs_IdcTestlits(CLAUSE, CLAUSE, LITPTR*);
+BOOL subs_Testlits(CLAUSE, CLAUSE);
+
+
+void subs_Init(void) 
+{
+  int i;
+
+  stamp = 0;
+  for (i = 0; i < subs__MAXLITS; i++)
+    multvec_i[i] = multvec_j[i] = 0;
+}
+
+
+static BOOL subs_TestlitsEq(CLAUSE c1, CLAUSE c2)
+/**********************************************************
+  INPUT:   Two clauses c1 and c2.
+  RETURNS: FALSE if c1 do not subsume c2 and TRUE otherwise.
+  CAUTION: None.
+***********************************************************/
+{
+  TERM  t1,t2;
+  int   i,j,n,k;
+  BOOL  found;
+
+  n    = clause_Length(c1);
+  k    = clause_Length(c2);
+
+  for (i = 0; i < n; i++){
+    j     = 0;
+    found = FALSE;
+    t1    = clause_GetLiteralTerm(c1,i);
+
+    do {
+      t2 = clause_GetLiteralTerm(c2,j);
+      cont_StartBinding();
+      if (unify_Match(cont_LeftContext(), t1, t2))
+	found = TRUE;
+      else{
+	if (symbol_Equal(term_TopSymbol(t1),term_TopSymbol(t2)) &&
+	    fol_IsEquality(fol_Atom(t1)) &&
+	    fol_IsEquality(fol_Atom(t2)) &&
+	    (clause_LiteralIsNotOrientedEquality(clause_GetLiteral(c1,i)) ||
+	     clause_LiteralIsNotOrientedEquality(clause_GetLiteral(c2,j)))) {
+	  cont_BackTrackAndStart();
+	  if (unify_Match(cont_LeftContext(),
+			  term_FirstArgument(fol_Atom(t1)),
+			  term_SecondArgument(fol_Atom(t2))) &&
+	      unify_Match(cont_LeftContext(),
+			  term_SecondArgument(fol_Atom(t1)),
+			  term_FirstArgument(fol_Atom(t2))))
+	    found = TRUE;
+	  else 
+	    j++;
+	}
+	else
+	  j++;
+      }
+      cont_BackTrack();
+      
+    } while (!found && j < k);
+       
+    if (!found)
+      return FALSE;
+  }
+
+  return TRUE;
+}
+
+
+static BOOL subs_STMultiIntern(int i, CLAUSE c1, CLAUSE c2)
+/**********************************************************
+  INPUT:   Integers i,j and two clauses c1 and c2
+           i and j stand for the i-th and the j-th literal 
+	   in the clause c1 respectively c2. 
+  RETURNS: FALSE if c1 does not multisubsume c2 and TRUE otherwise.
+  CAUTION: None.
+***********************************************************/
+{  
+  int  n,j;
+  TERM lit1,lit2;
+
+  j       = 0;
+  n       = clause_Length(c2);
+  lit1    = clause_GetLiteralTerm(c1,i);
+
+  while (j < n) {
+    if (multvec_j[j] != stamp) {
+      lit2    = clause_GetLiteralTerm(c2,j);
+      cont_StartBinding();
+      if (unify_Match(cont_LeftContext(),lit1,lit2)) {
+	if (i == (clause_Length(c1)-1)) {
+	  cont_BackTrack();
+	  return TRUE;
+	}
+	multvec_j[j] = stamp;
+	if (subs_STMultiIntern(i+1, c1, c2)) {
+	  cont_BackTrack();
+	  return TRUE;
+	}
+	multvec_j[j] = 0;
+      }
+      cont_BackTrack();
+      if (symbol_Equal(term_TopSymbol(lit1),term_TopSymbol(lit2)) &&
+	  fol_IsEquality(fol_Atom(lit1)) &&
+	  fol_IsEquality(fol_Atom(lit2)) &&
+	  (clause_LiteralIsNotOrientedEquality(clause_GetLiteral(c1,i)) ||
+	   clause_LiteralIsNotOrientedEquality(clause_GetLiteral(c2,j)))) {
+	cont_StartBinding();
+	if (unify_Match(cont_LeftContext(),
+			term_FirstArgument(fol_Atom(lit1)),
+			term_SecondArgument(fol_Atom(lit2))) &&
+	    unify_Match(cont_LeftContext(),
+			term_SecondArgument(fol_Atom(lit1)),
+			term_FirstArgument(fol_Atom(lit2)))) {
+	  if (i == (clause_Length(c1)-1)) {
+	    cont_BackTrack();
+	    return TRUE;
+	  }
+	  multvec_j[j] = stamp;
+	  if (subs_STMultiIntern(i+1, c1, c2)) {
+	    cont_BackTrack();
+	    return TRUE;
+	  }
+	  multvec_j[j] = 0;
+	}
+	cont_BackTrack();
+      }
+    }
+    j++;
+  }
+  return FALSE;
+}
+
+
+BOOL subs_STMulti(CLAUSE c1, CLAUSE c2)
+{
+  BOOL Result;
+  int  n;
+
+  n = clause_Length(c1);
+
+  /*printf("\n St-Multi: %d -> %d",clause_Number(c1),clause_Number(c2));*/
+
+  if (n > clause_Length(c2) ||
+      (n > 1 && !subs_TestlitsEq(c1,c2))) {
+    /*fputs(" Testlits failure ", stdout);*/
+    return(FALSE);
+  }
+
+  if (++stamp == NAT_MAX) {
+    int i;
+    stamp = 1;
+    for (i = 0; i < subs__MAXLITS; i++)
+    multvec_i[i] = multvec_j[i] = 0;
+  }
+  /*unify_SaveState();*/
+  Result = subs_STMultiIntern(0,c1,c2);
+  /*unify_CheckState();*/
+  return Result;
+}
+
+
+static BOOL subs_TestlitsEqExcept(CLAUSE C1, CLAUSE C2)
+{
+  TERM  t1,t2;
+  int   i,j,n,k;
+  BOOL  found;
+
+  n    = clause_Length(C1);
+  k    = clause_Length(C2);
+
+  i = 0;
+  while (multvec_i[i] == stamp && i < n)
+    i++;
+
+  while (i < n) {
+    j     = 0;
+    found = FALSE;
+    t1    = clause_GetLiteralTerm(C1,i);
+
+    do {
+      if (multvec_j[j] == stamp)
+	j++;
+      else {
+	t2 = clause_GetLiteralTerm(C2,j);
+	cont_StartBinding();
+	if (unify_MatchBindings(cont_LeftContext(), t1, t2))
+	  found = TRUE;
+	else {
+	  if (symbol_Equal(term_TopSymbol(t1),term_TopSymbol(t2)) &&
+	      fol_IsEquality(fol_Atom(t1)) &&
+	      fol_IsEquality(fol_Atom(t2)) &&
+	      (clause_LiteralIsNotOrientedEquality(clause_GetLiteral(C1,i)) ||
+	       clause_LiteralIsNotOrientedEquality(clause_GetLiteral(C2,j)))) {
+	    cont_BackTrackAndStart();
+	    if (unify_MatchBindings(cont_LeftContext(),
+				    term_FirstArgument(fol_Atom(t1)),
+				    term_SecondArgument(fol_Atom(t2))) &&
+		unify_MatchBindings(cont_LeftContext(),
+				    term_SecondArgument(fol_Atom(t1)),
+				    term_FirstArgument(fol_Atom(t2))))
+	      found = TRUE;
+	    else 
+	      j++;
+	  }
+	  else
+	    j++;
+	}
+	cont_BackTrack();
+      }  /* else */
+    } while (!found && (j < k));
+       
+    if (!found) 
+      return FALSE;
+    do
+      i++;
+    while (multvec_i[i] == stamp && i < n);
+  } /* while i < n */
+
+
+  return TRUE;
+}
+
+
+static BOOL subs_STMultiExceptIntern(CLAUSE C1, CLAUSE C2)
+{
+  int  n, i, j, k;
+  NAT  occs, occsaux;
+  TERM lit1,lit2;
+
+  i    = -1;
+  k    = 0;
+  occs = 0;
+  j    = 0;
+  n    = clause_Length(C2);
+
+  while (k < clause_Length(C1)) {
+    /* Select Literal with maximal number of variable occurrences. */
+    if (multvec_i[k] != stamp) {
+      if (i < 0) {
+	i    = k;
+	occs = term_NumberOfVarOccs(clause_GetLiteralAtom(C1,i));
+      } else
+	if ((occsaux = term_NumberOfVarOccs(clause_GetLiteralAtom(C1,k)))
+	    > occs) {
+	  i    = k;
+	  occs = occsaux;
+	}
+    }
+    k++;
+  }
+
+  if (i < 0)
+    return TRUE;
+
+  lit1 = clause_GetLiteralTerm(C1, i);
+  multvec_i[i] = stamp;
+
+  while (j < n) {
+    if (multvec_j[j] != stamp) {
+      lit2 = clause_GetLiteralTerm(C2, j);
+      cont_StartBinding();
+      if (unify_MatchBindings(cont_LeftContext(), lit1, lit2)) {
+	multvec_j[j] = stamp;
+	if (subs_STMultiExceptIntern(C1, C2)) {
+	  cont_BackTrack();
+	  return TRUE;
+	}
+	multvec_j[j] = 0;
+      }
+      cont_BackTrack();
+      if (symbol_Equal(term_TopSymbol(lit1),term_TopSymbol(lit2)) &&
+	  fol_IsEquality(fol_Atom(lit1)) &&
+	  fol_IsEquality(fol_Atom(lit2)) &&
+	  (clause_LiteralIsNotOrientedEquality(clause_GetLiteral(C1,i)) ||
+	   clause_LiteralIsNotOrientedEquality(clause_GetLiteral(C2,j)))) {
+	cont_StartBinding();
+	if (unify_MatchBindings(cont_LeftContext(),
+				term_FirstArgument(fol_Atom(lit1)),
+				term_SecondArgument(fol_Atom(lit2))) &&
+	    unify_MatchBindings(cont_LeftContext(),
+				term_SecondArgument(fol_Atom(lit1)),
+				term_FirstArgument(fol_Atom(lit2)))) {
+	  multvec_j[j] = stamp;
+	  if (subs_STMultiExceptIntern(C1, C2)) {
+	    cont_BackTrack();
+	    return TRUE;
+	  }
+	  multvec_j[j] = 0;
+	}
+	cont_BackTrack();
+      }
+    }
+    j++;
+  }
+  multvec_i[i] = 0;
+  return FALSE;
+}
+
+
+BOOL subs_STMultiExcept(CLAUSE C1, CLAUSE C2, int ExceptI, int ExceptJ)
+/**********************************************************
+  INPUT:   Two clauses and for each clause a literal that is
+           already bound to each other. If the literal value is negative,
+	   a general subsumption test is performed.
+  RETURNS: TRUE if the first clause subsumes the second one.
+  CAUTION: The weight of the clauses must be up to date!
+***********************************************************/
+{
+  BOOL Result;
+  int  n;
+
+  n = clause_Length(C1);
+
+  if (n > clause_Length(C2) ||
+      (clause_Weight(C1)-clause_LiteralWeight(clause_GetLiteral(C1,ExceptI))) >
+      (clause_Weight(C2)-clause_LiteralWeight(clause_GetLiteral(C2,ExceptJ))))
+    return FALSE;
+
+  if (++stamp == NAT_MAX) {
+    int i;
+    stamp = 1;
+    for (i = 0; i < subs__MAXLITS; i++)
+      multvec_i[i] = multvec_j[i] = 0;
+  }
+  multvec_i[ExceptI] = stamp;
+  multvec_j[ExceptJ] = stamp;
+
+  if (n > 1 && !subs_TestlitsEqExcept(C1, C2))
+    return FALSE;
+
+  /*unify_SaveState();*/
+  Result = subs_STMultiExceptIntern(C1, C2);
+  /*unify_CheckState();*/
+  return Result;
+}
+
+
+static BOOL subs_PartnerTest(CLAUSE C1, int c1l, int c1r, CLAUSE C2, int c2l, int c2r)
+/**********************************************************
+  INPUT:   Two clauses and for each clause a starting left index
+           and an exclusive right index.
+  RETURNS: TRUE if every literal inside the bounds of the first clause
+           can be matched against a literal inside the bounds of the
+	   second clause.
+  CAUTION: None.
+***********************************************************/
+{
+  TERM  t1,t2;
+  int   j;
+  BOOL  found;
+
+  if (c1l == c1r)
+    return TRUE;
+
+  while (multvec_i[c1l] == stamp && c1l < c1r)
+    c1l++;
+
+  if (c1l < c1r) {
+    if  (c2l == c2r)
+      return FALSE;
+    else
+      do {
+	j     = c2l;
+	found = FALSE;
+	t1    = clause_GetLiteralTerm(C1,c1l);
+
+	do {
+	  if (multvec_j[j] == stamp)
+	    j++;
+	  else {
+	    t2 = clause_GetLiteralTerm(C2,j);
+	    cont_StartBinding();
+	    if (unify_MatchBindings(cont_LeftContext(), t1, t2))
+	      found = TRUE;
+	    else {
+	      if (symbol_Equal(term_TopSymbol(t1),term_TopSymbol(t2)) &&
+		  fol_IsEquality(fol_Atom(t1)) &&
+		  fol_IsEquality(fol_Atom(t2)) &&
+		  (clause_LiteralIsNotOrientedEquality(clause_GetLiteral(C1,c1l)) ||
+		   clause_LiteralIsNotOrientedEquality(clause_GetLiteral(C2,j)))) {
+		cont_BackTrackAndStart();
+		if (unify_MatchBindings(cont_LeftContext(),
+					term_FirstArgument(fol_Atom(t1)),
+					term_SecondArgument(fol_Atom(t2))) &&
+		    unify_MatchBindings(cont_LeftContext(),
+					term_SecondArgument(fol_Atom(t1)),
+					term_FirstArgument(fol_Atom(t2))))
+		  found = TRUE;
+		else 
+		  j++;
+	      }
+	      else
+		j++;
+	    }
+	    cont_BackTrack();
+	  }  /* else */
+	} while (!found && (j < c2r));
+       
+	if (!found) 
+	  return FALSE;
+	do
+	  c1l++;
+	while (multvec_i[c1l] == stamp && c1l < c1r);
+      } while (c1l < c1r);
+  }
+  return TRUE;
+}
+
+
+static BOOL subs_SubsumesInternBasic(CLAUSE C1, int c1fa, int c1fs, int c1l, 
+				     CLAUSE C2, int c2fa, int c2fs, int c2l)
+{
+  int  i, j, n, k;
+  NAT  occs, occsaux;
+  TERM lit1,lit2;
+
+  i    = -1;
+  k    = clause_FirstLitIndex();
+  occs = 0;
+
+  while (k < c1l) {     /* Select literal with maximal variable occurrences. */
+    if (multvec_i[k] != stamp) {
+      if (i < 0) {
+	i    = k;
+	occs = term_NumberOfVarOccs(clause_GetLiteralAtom(C1,i));
+      } else
+	if ((occsaux = term_NumberOfVarOccs(clause_GetLiteralAtom(C1,k)))
+	    > occs) {
+	  i    = k;
+	  occs = occsaux;
+	}
+    }
+    k++;
+  }
+
+  if (i < 0)
+    return TRUE;
+
+  lit1         = clause_GetLiteralTerm(C1, i);
+  multvec_i[i] = stamp;
+
+  if (i < c1fa) {                 /* Only consider relevant partner literals */
+    j = clause_FirstLitIndex();
+    n = c2fa;
+  }
+  else if (i < c1fs) {
+    j = c2fa;
+    n = c2fs;
+  }
+  else {
+    j = c2fs;
+    n = c2l;
+  }
+
+  while (j < n) {
+    if (multvec_j[j] != stamp) {
+      lit2 = clause_GetLiteralTerm(C2, j);
+      cont_StartBinding();
+      if (unify_MatchBindings(cont_LeftContext(), lit1, lit2)) {
+	multvec_j[j] = stamp;
+	if (subs_SubsumesInternBasic(C1,c1fa,c1fs,c1l,C2,c2fa,c2fs,c2l)) {
+	  cont_BackTrack();
+	  return TRUE;
+	}
+	multvec_j[j] = 0;
+      }
+      cont_BackTrack();
+      if (symbol_Equal(term_TopSymbol(lit1),term_TopSymbol(lit2)) &&
+	  fol_IsEquality(fol_Atom(lit1)) &&
+	  fol_IsEquality(fol_Atom(lit2)) &&
+	  (clause_LiteralIsNotOrientedEquality(clause_GetLiteral(C1,i)) ||
+	   clause_LiteralIsNotOrientedEquality(clause_GetLiteral(C2,j)))) {
+	cont_StartBinding();
+	if (unify_MatchBindings(cont_LeftContext(),
+				term_FirstArgument(fol_Atom(lit1)),
+				term_SecondArgument(fol_Atom(lit2))) &&
+	    unify_MatchBindings(cont_LeftContext(),
+				term_SecondArgument(fol_Atom(lit1)),
+				term_FirstArgument(fol_Atom(lit2)))) {
+	  multvec_j[j] = stamp;
+	  if (subs_SubsumesInternBasic(C1,c1fa,c1fs,c1l,C2,c2fa,c2fs,c2l)) {
+	    cont_BackTrack();
+	    return TRUE;
+	  }
+	  multvec_j[j] = 0;
+	}
+	cont_BackTrack();
+      }
+    }
+    j++;
+  }
+  multvec_i[i] = 0;
+  return FALSE;
+}
+
+
+BOOL subs_SubsumesBasic(CLAUSE C1, CLAUSE C2, int ExceptI, int ExceptJ)
+/**********************************************************
+  INPUT:   Two clauses and for each clause a literal that are
+           already bound to each other. If the literal value is negative,
+	   a general subsumption test is performed.
+  RETURNS: TRUE if the first clause subsumes the second one with respect
+           to basic restrictions on the sort literals.
+  CAUTION: The weight of the clauses must be up to date!
+***********************************************************/
+{
+  BOOL Result;
+  int  c1fa,c1fs,c1l,c2fa,c2fs,c2l,lw1,lw2;
+
+  c1fa = clause_FirstAntecedentLitIndex(C1);
+  c1fs = clause_FirstSuccedentLitIndex(C1);
+  c1l  = clause_Length(C1);
+  c2fa = clause_FirstAntecedentLitIndex(C2);
+  c2fs = clause_FirstSuccedentLitIndex(C2);
+  c2l  = clause_Length(C2);
+
+  lw1 = (ExceptI >= clause_FirstLitIndex() ?
+	 clause_LiteralWeight(clause_GetLiteral(C1,ExceptI)) : 0);
+  lw2 = (ExceptJ >= clause_FirstLitIndex() ?
+	 clause_LiteralWeight(clause_GetLiteral(C2,ExceptJ)) : 0);
+
+  if (c1l > c2l ||                               /* Multiset restriction */
+      (clause_Weight(C1)-lw1) >  (clause_Weight(C2)-lw2)) {
+    return FALSE;
+  }
+
+  if (++stamp == NAT_MAX) {
+    int i;
+    stamp = 1;
+    for (i = 0; i < subs__MAXLITS; i++)
+      multvec_i[i] = multvec_j[i] = 0;
+  }
+
+  if (ExceptI >= clause_FirstLitIndex())
+    multvec_i[ExceptI] = stamp;
+  if (ExceptJ >= clause_FirstLitIndex())
+    multvec_j[ExceptJ] = stamp;
+
+  if (c1l > 1 && 
+      (!subs_PartnerTest(C1,clause_FirstConstraintLitIndex(C1),c1fa,
+			 C2,clause_FirstConstraintLitIndex(C2),c2fa) ||
+       !subs_PartnerTest(C1,c1fa,c1fs,C2,c2fa,c2fs) ||
+       !subs_PartnerTest(C1,c1fs,c1l,C2,c2fs,c2l)))
+    return FALSE;
+
+#ifdef CHECK
+  cont_SaveState();
+#endif
+
+  Result = subs_SubsumesInternBasic(C1,c1fa,c1fs,c1l,C2,c2fa,c2fs,c2l);
+
+#ifdef CHECK
+  cont_CheckState();
+#endif
+
+  return Result;
+}
+
+
+static BOOL subs_SubsumesInternWithSignature(int i, CLAUSE c1, CLAUSE c2, BOOL Variants, LIST* Bindings)
+/**********************************************************
+  INPUT:   
+  RETURNS: 
+  CAUTION: 
+***********************************************************/
+{  
+  int  n,j;
+  TERM lit1,lit2;
+  LIST NewBindings,Scan;
+
+  j           = 0;
+  n           = clause_Length(c2);
+  lit1        = clause_GetLiteralTerm(c1,i);
+  NewBindings = list_Nil();
+
+  while (j < n) {
+    if (multvec_j[j] != stamp) {
+      lit2    = clause_GetLiteralTerm(c2,j);
+      cont_StartBinding();
+      if (fol_SignatureMatch(lit1,lit2,&NewBindings,Variants)) {
+	if (i == (clause_Length(c1)-1)) {
+	  *Bindings = list_Nconc(NewBindings,*Bindings);
+	  return TRUE;
+	}
+	multvec_j[j] = stamp;
+	if (subs_SubsumesInternWithSignature(i+1, c1, c2,Variants,&NewBindings)) {
+	  *Bindings = list_Nconc(NewBindings,*Bindings);
+	  return TRUE;
+	}
+	multvec_j[j] = 0;
+      }      
+      for (Scan=NewBindings;!list_Empty(Scan);Scan=list_Cdr(Scan)) { /* Backtrack bindings */
+	if (symbol_IsVariable((SYMBOL)list_Car(Scan)))
+	  term_ClearBinding((SYMBOL)list_Car(Scan));
+	else
+	  symbol_ContextClearValue((SYMBOL)list_Car(Scan));
+      }
+      list_Delete(NewBindings);
+      NewBindings = list_Nil();
+      if (symbol_Equal(term_TopSymbol(fol_Atom(lit1)),term_TopSymbol(fol_Atom(lit2))) &&
+	  fol_IsEquality(fol_Atom(lit1))) {
+	if (fol_SignatureMatch(term_FirstArgument(fol_Atom(lit1)),
+			       term_SecondArgument(fol_Atom(lit2)), &NewBindings, Variants) &&
+	    fol_SignatureMatch(term_SecondArgument(fol_Atom(lit1)),
+			       term_FirstArgument(fol_Atom(lit2)), &NewBindings, Variants)) {
+	  if (i == (clause_Length(c1)-1)) {
+	    *Bindings = list_Nconc(NewBindings,*Bindings);
+	    return TRUE;
+	  }
+	  multvec_j[j] = stamp;
+	  if (subs_SubsumesInternWithSignature(i+1, c1, c2,Variants,&NewBindings)) {
+	    *Bindings = list_Nconc(NewBindings,*Bindings);
+	    return TRUE;
+	  }
+	  multvec_j[j] = 0;
+	}
+	for (Scan=NewBindings;!list_Empty(Scan);Scan=list_Cdr(Scan)) { /* Backtrack bindings */
+	  if (symbol_IsVariable((SYMBOL)list_Car(Scan)))
+	    term_ClearBinding((SYMBOL)list_Car(Scan));
+	  else
+	    symbol_ContextClearValue((SYMBOL)list_Car(Scan));
+	}
+	list_Delete(NewBindings);
+	NewBindings = list_Nil();
+      }
+    }
+    j++;
+  }
+  return FALSE;
+}
+
+BOOL subs_SubsumesWithSignature(CLAUSE C1, CLAUSE C2, BOOL Variants, LIST *Bindings)
+/**********************************************************
+  INPUT:   Two clauses .
+  RETURNS: TRUE if the first clause subsumes the second one where
+           we allow signature symbols to be matched as well.
+	   If <Variants> is TRUE variables must be mapped to variables.
+	   Returns the signature symbols that were bound.
+  EFFECT:  Symbol context bindings are established.
+***********************************************************/
+{
+  BOOL Result;
+
+  if (clause_Length(C1) > clause_Length(C2) ||
+      clause_NumOfSuccLits(C1) > clause_NumOfSuccLits(C2) ||
+      (clause_NumOfAnteLits(C1) + clause_NumOfConsLits(C1)) > 
+      (clause_NumOfAnteLits(C2) + clause_NumOfConsLits(C2))) {   /* Multiset restriction */
+    return FALSE;
+  }
+
+  if (++stamp == NAT_MAX) {
+    int i;
+    stamp = 1;
+    for (i = 0; i < subs__MAXLITS; i++)
+      multvec_i[i] = multvec_j[i] = 0;
+  }
+
+  term_NewMark();
+  Result =  subs_SubsumesInternWithSignature(clause_FirstLitIndex(),C1,C2,Variants, Bindings);
+  *Bindings = list_DeleteElementIf(*Bindings, (BOOL (*)(POINTER)) symbol_IsVariable);
+  return Result;
+}
+
+static BOOL subs_SubsumesIntern(CLAUSE C1, int c1fs, int c1l, CLAUSE C2, int c2fs, int c2l)
+{
+  int  i, j, n, k;
+  NAT  occs, occsaux;
+  TERM lit1,lit2;
+
+  i    = -1;
+  k    = clause_FirstLitIndex();
+  occs = 0;
+
+  while (k < c1l) {     /* Select literal with maximal variable occurrences. */
+    if (multvec_i[k] != stamp) {
+      if (i < 0) {
+	i    = k;
+	occs = term_NumberOfVarOccs(clause_GetLiteralAtom(C1,i));
+      } else
+	if ((occsaux = term_NumberOfVarOccs(clause_GetLiteralAtom(C1,k)))
+	    > occs) {
+	  i    = k;
+	  occs = occsaux;
+	}
+    }
+    k++;
+  }
+
+  if (i < 0)
+    return TRUE;
+
+  lit1         = clause_GetLiteralTerm(C1, i);
+  multvec_i[i] = stamp;
+
+  if (i < c1fs) {                  /* Only consider relevant partner literals */
+    j = clause_FirstLitIndex();
+    n = c2fs;
+  }
+  else {
+    j = c2fs;
+    n = c2l;
+  }
+
+  while (j < n) {
+    if (multvec_j[j] != stamp) {
+      lit2 = clause_GetLiteralTerm(C2, j);
+      cont_StartBinding();
+      if (unify_MatchBindings(cont_LeftContext(), lit1, lit2)) {
+	multvec_j[j] = stamp;
+	if (subs_SubsumesIntern(C1,c1fs,c1l,C2,c2fs,c2l)) {
+	  cont_BackTrack();
+	  return TRUE;
+	}
+	multvec_j[j] = 0;
+      }
+      cont_BackTrack();
+      if (symbol_Equal(term_TopSymbol(lit1),term_TopSymbol(lit2)) &&
+	  fol_IsEquality(fol_Atom(lit1)) &&
+	  fol_IsEquality(fol_Atom(lit2)) &&
+	  (clause_LiteralIsNotOrientedEquality(clause_GetLiteral(C1,i)) ||
+	   clause_LiteralIsNotOrientedEquality(clause_GetLiteral(C2,j)))) {
+	cont_StartBinding();
+	if (unify_MatchBindings(cont_LeftContext(),
+				term_FirstArgument(fol_Atom(lit1)),
+				term_SecondArgument(fol_Atom(lit2))) &&
+	    unify_MatchBindings(cont_LeftContext(),
+				term_SecondArgument(fol_Atom(lit1)),
+				term_FirstArgument(fol_Atom(lit2)))) {
+	  multvec_j[j] = stamp;
+	  if (subs_SubsumesIntern(C1,c1fs,c1l,C2,c2fs,c2l)) {
+	    cont_BackTrack();
+	    return TRUE;
+	  }
+	  multvec_j[j] = 0;
+	}
+	cont_BackTrack();
+      }
+    }
+    j++;
+  }
+  multvec_i[i] = 0;
+  return FALSE;
+}
+
+
+BOOL subs_Subsumes(CLAUSE C1, CLAUSE C2, int ExceptI, int ExceptJ)
+/**********************************************************
+  INPUT:   Two clauses and for each clause a literal that is
+           already bound to each other. If the literal value is negative,
+	   a general subsumption test is performed.
+  RETURNS: TRUE if the first clause subsumes the second one.
+  CAUTION: The weight of the clauses must be up to date!
+***********************************************************/
+{
+  BOOL Result;
+  int  c1fs, c1l, c2fs, c2l, lw1, lw2;
+
+  c1fs   = clause_FirstSuccedentLitIndex(C1);
+  c1l    = clause_Length(C1);
+  c2fs   = clause_FirstSuccedentLitIndex(C2);
+  c2l    = clause_Length(C2);
+  
+  lw1 = (ExceptI >= clause_FirstLitIndex() ?
+	 clause_LiteralWeight(clause_GetLiteral(C1,ExceptI)) : 0);
+  lw2 = (ExceptJ >= clause_FirstLitIndex() ?
+	 clause_LiteralWeight(clause_GetLiteral(C2,ExceptJ)) : 0);
+
+  if (c1l > c2l ||                               /* Multiset restriction */
+      (clause_Weight(C1) - lw1) > (clause_Weight(C2) - lw2))
+    return FALSE;
+
+  if (++stamp == NAT_MAX) {
+    int i;
+    stamp = 1;
+    for (i = 0; i < subs__MAXLITS; i++)
+      multvec_i[i] = multvec_j[i] = 0;
+  }
+
+  if (ExceptI >= clause_FirstLitIndex())
+    multvec_i[ExceptI] = stamp;
+  if (ExceptJ >= clause_FirstLitIndex())
+    multvec_j[ExceptJ] = stamp;
+
+  if (c1l > 1 && 
+      (!subs_PartnerTest(C1,clause_FirstConstraintLitIndex(C1),c1fs,
+			 C2,clause_FirstConstraintLitIndex(C2),c2fs) ||
+       !subs_PartnerTest(C1,c1fs,c1l,C2,c2fs,c2l)))
+    return FALSE;
+
+#ifdef CHECK
+  cont_SaveState();
+#endif
+
+  Result = subs_SubsumesIntern(C1,c1fs,c1l,C2,c2fs,c2l);
+  
+#ifdef CHECK
+  cont_CheckState();
+#endif
+
+  return Result;
+}
+
+
+
+
+BOOL subs_ST(int i, int j, CLAUSE c1, CLAUSE c2)
+/**********************************************************
+  INPUT:   Integers i,j and two clauses c1 and c2.
+           i and j stand for the i-th and the j-th literal 
+	   in the clause c1 respectively c2.
+  RETURNS: FALSE if c1 does not subsume c2 and TRUE otherwise.
+  CAUTION: None.
+***********************************************************/
+{  
+  cont_StartBinding();
+
+  while ((j < clause_Length(c2)) &&
+	 !(unify_Match(cont_LeftContext(),
+		       clause_GetLiteralTerm(c1,i),
+		       clause_GetLiteralTerm(c2,j)))){
+    j++;
+    cont_BackTrackAndStart();
+  }
+
+  if (j >= clause_Length(c2)) {
+    cont_BackTrack();
+    return FALSE;
+  }
+
+  if ((i == (clause_Length(c1)-1)) || subs_ST(i+1, 0, c1, c2))
+    return TRUE;
+  else
+    cont_BackTrack();
+
+  if (++j == clause_Length(c2))
+    return FALSE;
+
+  return subs_ST(i, j, c1, c2);
+}
+
+
+BOOL subs_Testlits(CLAUSE c1, CLAUSE c2)
+/**********************************************************
+  INPUT:   Two clauses c1 and c2.
+  RETURNS: FALSE if c1 do not subsume c2 and TRUE otherwise.
+  CAUTION: None.
+***********************************************************/
+{
+  TERM   t1;
+  int  i,j;
+  BOOL found;
+
+  for (i = 0; i < clause_Length(c1); i++){
+    j     = 0;
+    found = FALSE;
+    t1    = clause_GetLiteralTerm(c1,i);
+
+    do {
+      cont_StartBinding();
+      if (!(found = unify_Match(cont_LeftContext(), t1, clause_GetLiteralTerm(c2,j))))
+	j++;
+      cont_BackTrack();
+      
+    } while (!found && (j < clause_Length(c2)));
+       
+    if (!found)
+      return FALSE;
+  }
+
+  return TRUE;
+}
+
+
+static LIST subs_GetVariables(TERM t)
+/**********************************************************
+  INPUT:   A term.
+  RETURNS: The list of non bound variables of the term.
+  CAUTION: None.
+***********************************************************/
+{
+  LIST scan,insert,symbols,end;
+
+  symbols = term_VariableSymbols(t);
+  insert  = symbols;
+  end     = list_Nil();
+
+  for (scan = symbols; !list_Empty(scan); scan = list_Cdr(scan)) {
+    if (!cont_VarIsBound(cont_LeftContext(), (SYMBOL)list_Car(scan))) {
+      end    = insert;
+      list_Rplaca(insert, list_Car(scan));
+      insert = list_Cdr(insert);
+    }
+  }
+
+  if (!list_Empty(insert)) {
+    list_Delete(insert);
+    if (list_Empty(end))
+      symbols = list_Nil();
+    else
+      list_Rplacd(end,list_Nil());
+  }
+
+  return(symbols);
+}
+
+
+static BOOL subs_SubsumptionPossible(CLAUSE c1, CLAUSE c2)
+/**********************************************************
+  INPUT:   Two clauses c1 and c2.
+  RETURNS: TRUE if every literal in c1 can independently be
+           matched to a literal in c2.
+  CAUTION: None.
+***********************************************************/
+{
+  int i,j;
+
+  for (i = 0; i < clause_Length(c1); i++) {
+    for (j = 0; j < clause_Length(c2); j++) {
+      cont_StartBinding();
+      if (unify_Match(cont_LeftContext(),
+		      clause_GetLiteralTerm(c1,i),
+		      clause_GetLiteralTerm(c2,j)))
+	j = clause_Length(c2) + 1;
+      cont_BackTrack();
+    }
+    if (j == clause_Length(c2))
+      return FALSE;
+  }
+
+  return TRUE;
+}
+
+
+BOOL subs_IdcTestlits(CLAUSE c1, CLAUSE c2, LITPTR* litptr)
+/**********************************************************
+  INPUT:   Two clauses c1, c2  and a pointer to a litptr structure.
+  RETURNS: FALSE if c1 can not independently be matched 
+           to c2 and TRUE otherwise.
+  CAUTION: A structure is build and litptr points to that structure.
+***********************************************************/
+{
+  LIST  TermIndexlist,VarSymbList,TermSymbList;
+  int   i;
+
+  if (subs_SubsumptionPossible(c1,c2)) {
+ 
+    TermIndexlist  = list_Nil();
+    VarSymbList    = list_Nil();
+    TermSymbList   = list_Nil();
+ 
+    for (i = 0; i < clause_Length(c1); i++) {
+      VarSymbList = subs_GetVariables(clause_GetLiteralTerm(c1,i));
+   
+      if (VarSymbList != list_Nil()){
+	TermIndexlist = list_Cons((POINTER)i, TermIndexlist);         
+	TermSymbList  = list_Cons(VarSymbList,TermSymbList);
+      } 
+    }
+  
+    *litptr = litptr_Create(TermIndexlist,TermSymbList); 
+
+    list_Delete(TermSymbList);
+    list_Delete(TermIndexlist);
+
+    return TRUE;
+  }
+  return FALSE;
+}
+
+
+static BOOL subs_SubsumptionVecPossible(CLAUSE c1, int vec, CLAUSE c2)
+/**********************************************************
+  INPUT:   Two clauses c1 and c2 and a vector pointer.
+  RETURNS: TRUE if all literals in c1 which indexes stand
+           in the vector with bottom pointer vec can 
+	   independently be matched to a literal in c2.
+  CAUTION: None.
+***********************************************************/
+{
+  int i,j;
+
+  for (i = vec; i < vec_ActMax(); i++) {
+    for (j = 0; j < clause_Length(c2); j++) {
+      cont_StartBinding();
+      if (unify_Match(cont_LeftContext(),
+		      clause_GetLiteralTerm(c1, (int) vec_GetNth(i)), 
+		      clause_GetLiteralTerm(c2,j)))
+	j = clause_Length(c2) + 1;
+      cont_BackTrack();
+    }
+    if (j == clause_Length(c2))
+      return FALSE;
+  }
+  
+  return TRUE;
+}
+
+
+static BOOL subs_SubsumptionVecPossibleEq(CLAUSE c1, int vec, CLAUSE c2)
+/**********************************************************
+  INPUT:   Two clauses c1 and c2 and a vector pointer.
+  RETURNS: TRUE if all literals in c1 which indexes stand
+           in the vector with bottom pointer vec can 
+	   independently be matched to a literal in c2.
+  CAUTION: None.
+***********************************************************/
+{
+  int    i,j,n;
+  TERM   lit1,lit2;
+  
+  n = clause_Length(c2);
+  for (i = vec; i < vec_ActMax(); i++) {
+    lit1 = clause_GetLiteralTerm(c1, (int) vec_GetNth(i));
+    for (j=0;j<n;j++) {
+      lit2 = clause_GetLiteralTerm(c2,j);
+      cont_StartBinding();
+      if (unify_Match(cont_LeftContext(),lit1,lit2)) {
+	j = n + 1;
+	cont_BackTrack();
+      }
+      else {
+	cont_BackTrack();
+	if (symbol_Equal(term_TopSymbol(lit1),term_TopSymbol(lit2)) &&
+	    fol_IsEquality(fol_Atom(lit1)) &&
+	    fol_IsEquality(fol_Atom(lit2)) &&
+	    (clause_LiteralIsNotOrientedEquality(
+               clause_GetLiteral(c1, (int)vec_GetNth(i))) ||
+	     clause_LiteralIsNotOrientedEquality(clause_GetLiteral(c2,j)))) {
+	  cont_StartBinding();
+	  if (unify_Match(cont_LeftContext(),
+			  term_FirstArgument(fol_Atom(lit1)),
+			  term_SecondArgument(fol_Atom(lit2))) &&
+	      unify_Match(cont_LeftContext(),
+			  term_SecondArgument(fol_Atom(lit1)),
+			  term_FirstArgument(fol_Atom(lit2))))
+	      j = n+1;
+	  cont_BackTrack();
+	}
+      }
+    }
+    if (j==n)
+	return FALSE;
+  }
+  
+  return TRUE;
+}
+
+
+static BOOL subs_IdcVecTestlits(CLAUSE c1, int vec, CLAUSE c2, LITPTR* litptr)
+/**********************************************************
+  INPUT:   Two clauses c1, c2, a pointer to a literal structure and
+           a vector pointer.
+  RETURNS: FALSE if the literals of c1 which are designated by
+           the elements of vec do not subsume c2 and TRUE otherwise.
+  CAUTION: A structure is build and litptr points to that structure.
+***********************************************************/
+{
+  LIST  TermIndexlist,VarSymbList,TermSymbList;
+  int   i;
+  
+  if (subs_SubsumptionVecPossible(c1,vec,c2)) {
+    
+    TermIndexlist  = list_Nil();
+    VarSymbList    = list_Nil();
+    TermSymbList   = list_Nil();
+    
+    for (i = vec; i < vec_ActMax(); i++) {
+      VarSymbList =
+	subs_GetVariables(clause_GetLiteralTerm(c1, (int) vec_GetNth(i)));
+   
+      if (VarSymbList != list_Nil()){
+	TermIndexlist = list_Cons(vec_GetNth(i), TermIndexlist);         
+	TermSymbList  = list_Cons(VarSymbList,TermSymbList);
+      } 
+    }
+	    
+    *litptr = litptr_Create(TermIndexlist,TermSymbList); 
+
+    list_Delete(TermSymbList);
+    list_Delete(TermIndexlist);
+	
+    return TRUE;
+  }
+  return FALSE;
+}
+
+
+static BOOL subs_IdcVecTestlitsEq(CLAUSE c1, int vec, CLAUSE c2,
+				  LITPTR* litptr)
+/**********************************************************
+  INPUT:   Two clauses c1, c2, a pointer to a literal structure and
+           a vector pointer.
+  RETURNS: FALSE if the literals of c1 which are designated by
+           the elements of vec do not subsume c2 and TRUE otherwise.
+  CAUTION: A structure is build and litptr points to that structure.
+***********************************************************/
+{
+  LIST  TermIndexlist,VarSymbList,TermSymbList;
+  int   i;
+  
+  if (subs_SubsumptionVecPossibleEq(c1,vec,c2)) {
+    
+    TermIndexlist  = list_Nil();
+    VarSymbList    = list_Nil();
+    TermSymbList   = list_Nil();
+    
+    for (i = vec; i < vec_ActMax(); i++){
+      VarSymbList =
+	subs_GetVariables(clause_GetLiteralTerm(c1, (int) vec_GetNth(i)));
+   
+      if (VarSymbList != list_Nil()){
+	TermIndexlist = list_Cons(vec_GetNth(i), TermIndexlist);         
+	TermSymbList  = list_Cons(VarSymbList,TermSymbList);
+      } 
+    }
+	    
+    *litptr = litptr_Create(TermIndexlist,TermSymbList); 
+
+    list_Delete(TermSymbList);
+    list_Delete(TermIndexlist);
+	
+    return TRUE;
+  }
+  return FALSE;
+}
+
+
+static void subs_CompVec(LITPTR litptr)
+/**********************************************************
+  INPUT:   A  LITPTR pointer.
+  RETURNS: None.
+  CAUTION: Indexes are pushed on the vector. These indexes build
+           a component with respect to the structure litptr and to the 
+	   actual bindings.
+***********************************************************/
+{
+  LIST complist, end, scan;
+  int  lit,n,i,j;
+
+  n        = litptr_Length(litptr);
+  complist = list_Nil();
+
+
+  if (n > 0){
+    for (j = 0; j < n; j++) {
+      if (!literal_GetUsed(litptr_Literal(litptr,j))) {
+	complist = list_Cons((POINTER)j,complist);
+	vec_Push((POINTER)literal_GetLitIndex(litptr_Literal(litptr,j)));
+	literal_PutUsed(litptr_Literal(litptr,j), TRUE);
+	j = n + 1;
+      }
+    }
+
+    if (j != n) {
+      end = complist;
+      for (scan = complist; !list_Empty(scan); scan = list_Cdr(scan)) {
+	lit = (int)list_Car(scan);
+	for (i = 0; i < n; i++) {
+	  if (!literal_GetUsed(litptr_Literal(litptr,i)) &&
+	     list_HasIntersection(literal_GetLitVarList(litptr_Literal(litptr,lit)),
+				  literal_GetLitVarList(litptr_Literal(litptr,i)))) {
+	    list_Rplacd(end,list_List((POINTER)i));
+	    end = list_Cdr(end);
+	    vec_Push((POINTER)literal_GetLitIndex(litptr_Literal(litptr,i)));
+	    literal_PutUsed(litptr_Literal(litptr,i), TRUE);
+	  }
+	}
+      }
+      list_Delete(complist);
+    }
+  }
+}
+
+
+static BOOL subs_StVec(int i, int j, CLAUSE c1, CLAUSE c2)
+/**********************************************************
+  INPUT:   Integers i,j and two clauses c1 and c2.
+           i is a pointer to vector and represents a 
+	   literal in clause c1 and j stand for the j-th 
+	   literal in the clause c2.
+  RETURNS: FALSE if c1 do not subsume c2 and TRUE otherwise.
+  CAUTION: None.
+***********************************************************/
+{  
+  int a;
+    
+  if (j >= clause_Length(c2))
+    return FALSE;
+    
+  a = j;
+  
+  cont_StartBinding();
+
+  while ((a < clause_Length(c2)) && 
+	 !(unify_Match(cont_LeftContext(),
+		       clause_GetLiteralTerm(c1, (int) vec_GetNth(i)),
+		       clause_GetLiteralTerm(c2,a)))){
+    a++;
+    cont_BackTrackAndStart();
+  }
+  
+  if (a >= clause_Length(c2)) {
+    cont_BackTrack();
+    return FALSE;
+  }
+
+  if ((i == (vec_ActMax()-1)) || subs_StVec(i+1, 0, c1, c2))
+    return TRUE;
+  else 
+    cont_BackTrack();
+
+  return subs_StVec(i, a+1, c1, c2);
+}
+
+
+static int subs_SearchTop(CLAUSE c1, int vec, CLAUSE c2)
+/**********************************************************
+  INPUT:   Two clauses c1, c2, a vector pointer vec.
+  RETURNS: The index of that literal in c1 which has the least positive
+           matching tests with the literals in c2.
+  CAUTION: None.
+***********************************************************/
+{
+  int index, i, j, zaehler;
+
+  index = (int)vec_GetNth(vec);
+
+  for (i = vec; i < vec_ActMax(); i++) {
+    zaehler = 0;
+    j       = 0;
+    while (j < clause_Length(c2) && zaehler < 2) {
+      cont_StartBinding();
+      if (unify_Match(cont_LeftContext(),
+		      clause_GetLiteralTerm(c1, (int) vec_GetNth(i)),
+		      clause_GetLiteralTerm(c2,j))) {
+	zaehler++;
+      }
+      cont_BackTrack();
+      j++;
+    }
+
+    if (zaehler == 0 || zaehler == 1) {
+      index = (int)vec_GetNth(i);
+      return index;
+    }
+  }
+  return index;
+}
+
+
+static BOOL subs_TcVec(CLAUSE c1, int vec, CLAUSE c2)
+/**********************************************************
+  INPUT:   Two clauses c1, c2, a vector pointer vec.
+  RETURNS: FALSE if the literals of c1 which are designated by
+           the elements of vec do not subsume c2 and TRUE otherwise.
+  CAUTION: None.
+***********************************************************/
+{
+  int a,top_index;
+  a    = 0;
+
+  top_index = subs_SearchTop(c1,vec,c2);
+    
+  do {
+    cont_StartBinding();
+    while ((a < clause_Length(c2)) &&
+	   !(unify_Match(cont_LeftContext(),
+			 clause_GetLiteralTerm(c1,top_index),
+			 clause_GetLiteralTerm(c2,a)))) {
+      a++;
+      cont_BackTrackAndStart();
+    }
+    
+    if (a >= clause_Length(c2)){
+      cont_BackTrack();
+      return FALSE;
+    }
+
+    if ((vec - vec_ActMax()) == 1) 
+      return TRUE;		
+    
+    if (subs_InternIdc(c1, vec, c2))
+      return TRUE;
+    else {
+      cont_BackTrack();	/* Dies ist der 'Hurra' Fall.*/
+      a++;			
+    }
+
+  } while (a < clause_Length(c2));
+  
+  return FALSE;
+}
+
+static BOOL subs_TcVecEq(CLAUSE c1, int vec, CLAUSE c2)
+/**********************************************************
+  INPUT:   Two clauses c1, c2, a vector pointer vec.
+  RETURNS: FALSE if the literals of c1 which are designated by
+           the elements of vec do not subsume c2 and TRUE otherwise.
+  CAUTION: None.
+***********************************************************/
+{
+  int a,top_index;
+  BOOL search;
+  TERM lit1,lit2;
+
+  a         = 0;
+  top_index = subs_SearchTop(c1,vec,c2);
+  lit1      = clause_GetLiteralTerm(c1,top_index);
+    
+  do {
+    search = TRUE;
+
+    while (a < clause_Length(c2) && search) {
+      lit2 = clause_GetLiteralTerm(c2,a);
+      cont_StartBinding();
+      if (unify_Match(cont_LeftContext(),lit1,lit2))
+	search = FALSE;
+      else {
+	if (symbol_Equal(term_TopSymbol(lit1),term_TopSymbol(lit2)) &&
+	    fol_IsEquality(fol_Atom(lit1)) &&
+	    fol_IsEquality(fol_Atom(lit2)) &&
+	    (clause_LiteralIsNotOrientedEquality(clause_GetLiteral(c1,top_index)) ||
+	     clause_LiteralIsNotOrientedEquality(clause_GetLiteral(c2,a)))) {
+	  cont_BackTrackAndStart();
+	  if (unify_Match(cont_LeftContext(),
+			  term_FirstArgument(fol_Atom(lit1)),
+			  term_SecondArgument(fol_Atom(lit2))) &&
+	      unify_Match(cont_LeftContext(),
+			  term_SecondArgument(fol_Atom(lit1)),
+			  term_FirstArgument(fol_Atom(lit2))))
+	    search = FALSE;
+	}
+	if (search) {
+	  a++;
+	  cont_BackTrack();
+	}
+      }
+    }
+    
+    if (a >= clause_Length(c2)) {
+      cont_BackTrack();
+      return FALSE;
+    }
+
+    if ((vec_ActMax() - vec) == 1) 
+      return TRUE;		
+    
+    if (subs_InternIdcEq(c1, vec, c2))
+      return TRUE;
+    else {
+      cont_BackTrack();
+      a++;			
+    }
+
+  } while (a < clause_Length(c2));
+  
+  return FALSE;
+}
+
+
+static BOOL subs_InternIdc(CLAUSE c1, int vec, CLAUSE c2)
+/**********************************************************
+  INPUT:   Two clauses c1, c2, a vector pointer vec.
+  RETURNS: FALSE if the literals of c1 which are designed by
+           the elements of vec do not subsume c2 and TRUE otherwise.
+  CAUTION: 
+***********************************************************/
+{
+  int        locvec;
+  LITPTR litptr;
+  
+  
+  if (!subs_IdcVecTestlits(c1,vec,c2,&litptr))
+    return FALSE;
+
+  locvec = vec_ActMax();
+  
+  do {
+    subs_CompVec(litptr);	
+    if (!vec_IsMax(locvec)) {
+      if (!subs_TcVec(c1,locvec,c2)) {
+	vec_SetMax(locvec);
+	litptr_Delete(litptr);
+	return FALSE;
+      } 
+      else
+	vec_SetMax(locvec);
+    }
+  } while (!litptr_AllUsed(litptr));
+
+  litptr_Delete(litptr);
+  
+  return TRUE;
+}
+
+
+static BOOL subs_InternIdcEq(CLAUSE c1, int vec, CLAUSE c2)
+/**********************************************************
+  INPUT:   Two clauses c1, c2, a vector pointer vec.
+  RETURNS: FALSE if the literals of c1 which are designed by
+           the elements of vec do not subsume c2 and TRUE otherwise.
+  CAUTION: 
+***********************************************************/
+{
+  int        locvec;
+  LITPTR litptr;
+  
+  
+  if (!subs_IdcVecTestlitsEq(c1,vec,c2,&litptr))
+    return FALSE;
+
+  locvec = vec_ActMax();
+  
+  do {
+    subs_CompVec(litptr);	
+    if (!vec_IsMax(locvec)) {
+      if (!subs_TcVecEq(c1,locvec,c2)) {
+	vec_SetMax(locvec);
+	litptr_Delete(litptr);
+	return FALSE;
+      } 
+      else
+	vec_SetMax(locvec);
+    }
+
+  } while (!litptr_AllUsed(litptr));
+
+  litptr_Delete(litptr);
+  
+  return TRUE;
+}
+
+
+BOOL subs_Idc(CLAUSE c1, CLAUSE c2)
+/**********************************************************
+  INPUT:   Two clauses c1, c2.
+  RETURNS: FALSE if c1 do not subsume c2 and TRUE otherwise.
+  CAUTION: 
+***********************************************************/
+{
+  int  i,vec;
+  BOOL Result;
+
+  vec = vec_ActMax();
+
+  for (i = 0; i < clause_Length(c1); i++)
+    vec_Push((POINTER) i);
+
+  Result = subs_InternIdc(c1,vec,c2);
+    
+  vec_SetMax(vec);
+
+  cont_Reset();
+    
+  return Result;
+}
+
+
+BOOL subs_IdcEq(CLAUSE c1, CLAUSE c2)
+/**********************************************************
+  INPUT:   Two clauses c1, c2.
+  RETURNS: FALSE if c1 do not subsume c2 and TRUE otherwise.
+  CAUTION: 
+***********************************************************/
+{
+  int  i,vec;
+  BOOL Result;
+
+  /*fputs("\n Idc on:  ", stdout); clause_Print(c1);
+    putchar('\t'); clause_Print(c2); */ 
+  vec = vec_ActMax();
+
+  for (i = 0; i < clause_Length(c1); i++)
+    vec_Push((POINTER) i);
+
+  Result = subs_InternIdcEq(c1,vec,c2);
+    
+  vec_SetMax(vec);
+
+  cont_Reset();
+
+  /*printf(" Result: %s ",(Result ? "TRUE" : "FALSE"));*/
+
+  return Result;
+}
+
+
+BOOL subs_IdcEqMatch(CLAUSE c1, CLAUSE c2, SUBST subst)
+/**********************************************************
+  INPUT:   Two clauses c1, c2.
+  RETURNS: FALSE if c1 do not subsume c2 and TRUE otherwise.
+  CAUTION: 
+***********************************************************/
+{
+  int  i,vec;
+  BOOL Result;
+
+  /* fputs("\n Idc on:  ", stdout); clause_Print(c1);
+     putchar('\t'); clause_Print(c2);   DBG */
+  vec = vec_ActMax();
+
+  for (i = 0; i < clause_Length(c1); i++)
+    vec_Push((POINTER) i);
+
+  i = 0;        /* Doesn't matter, there is a general cont_Reset below */
+  unify_EstablishMatcher(cont_LeftContext(), subst);
+
+  Result = subs_InternIdcEq(c1,vec,c2);
+    
+  vec_SetMax(vec);
+
+  cont_Reset();
+
+  /*fputs("\nsubs_Idc end: ",stdout); clause_Print(c1); clause_Print(c2); DBG */
+
+  return Result;
+}
+
+
+static BOOL subs_SubsumptionVecPossibleRes(CLAUSE c1, int vec,
+					   int beg, int end)
+/**********************************************************
+  INPUT:   Two clauses c1 and c2 and three vector pointer
+           vec,beg and end.
+  RETURNS: TRUE if all literals in c1 which indexes stand
+           in the vector with bottom pointer vec can 
+	   independently be matched to a literal in c2
+	   which indexes stand in the vector between the
+	   pointers beg and end (exclusive).
+  CAUTION: None.
+***********************************************************/
+{
+  int  j,i;
+
+  for (i = vec; i < vec_ActMax(); i++) {
+    for (j = beg; j < end; j++){
+      cont_StartBinding();
+      if (unify_Match(cont_LeftContext(),
+		      clause_GetLiteralTerm(c1, (int) vec_GetNth(i)), 
+		      clause_GetLiteralTerm(c1, (int) vec_GetNth(j))))
+	j = end+1;
+      cont_BackTrack();
+    }
+    if (j == end)
+      return FALSE;
+  }
+  return TRUE;
+}
+
+
+static BOOL subs_IdcVecTestlitsRes(CLAUSE c1, int vec,
+				   int beg, int end, LITPTR* litptr)
+/**********************************************************
+  INPUT:   A clause c1, a pointer to a literal structure and
+           three  vector pointer vec, beg and end.
+  RETURNS: FALSE if the literals of c1 which are designated by
+           the elements of vec can not be matched independently
+	   to literal in c2 which are designated by the elements
+	   of the vector between the pointers beg and end (exclusive).
+  CAUTION: A structure is build and litptr points to that structure.
+***********************************************************/
+{
+  LIST  TermIndexlist,VarSymbList,TermSymbList;
+  int   i;
+  
+  if (subs_SubsumptionVecPossibleRes(c1,vec,beg,end)) {
+    
+    TermIndexlist  = list_Nil();
+    VarSymbList    = list_Nil();
+    TermSymbList   = list_Nil();
+    
+    for (i = vec; i < vec_ActMax(); i++) {
+      VarSymbList =
+	subs_GetVariables(clause_GetLiteralTerm(c1, (int) vec_GetNth(i)));
+      
+      if (VarSymbList != list_Nil()) {
+	TermIndexlist = list_Cons(vec_GetNth(i), TermIndexlist);         
+	TermSymbList  = list_Cons(VarSymbList,TermSymbList);
+      } 
+    }
+    
+    *litptr = litptr_Create(TermIndexlist,TermSymbList); 
+    
+    list_Delete(TermSymbList);
+    list_Delete(TermIndexlist);
+    
+    return TRUE;
+  }
+  return FALSE;
+}
+
+
+static int subs_SearchTopRes(CLAUSE c1, int vec, int beg, int end)
+/**********************************************************
+  INPUT:   A clause c1, three vector pointers vec, beg and end.
+  RETURNS: The index of that literal in c1 which has the least positive
+           matching tests with the literals in c2 with respect to
+	   vector and the vector pointers beg and end.
+  CAUTION: None.
+***********************************************************/
+{
+  int  index,i,j,zaehler;
+    
+  index = (int) vec_GetNth(vec);
+
+  for (i = vec; i < vec_ActMax(); i++) {
+    zaehler = 0;
+    j       = beg;
+    while ((j < end) && (zaehler < 2)) {
+      cont_StartBinding();
+      if (unify_Match(cont_LeftContext(),
+		      clause_GetLiteralTerm(c1, (int) vec_GetNth(i)),
+		      clause_GetLiteralTerm(c1, (int) vec_GetNth(j)))) {
+	zaehler++;
+      }
+      cont_BackTrack();
+      j++;
+    }
+
+    if (zaehler == 0 || zaehler == 1) {
+      index = (int)vec_GetNth(i);
+      return index;
+    }
+  }
+  return index;
+}
+
+
+static BOOL subs_TcVecRes(CLAUSE c1, int vec, int beg, int end)
+/**********************************************************
+  INPUT:   A clause c1, three vector pointers vec,beg and end.
+  RETURNS: FALSE if the literals of c1 which are designated by
+           the elements of vec do not subsume c2 with 
+	   respect to the vector and the vector pointers
+	   beg and end and TRUE otherwise.
+  CAUTION: None.
+***********************************************************/
+{
+  int  a,top_index;
+
+  a = beg;
+
+  top_index = subs_SearchTopRes(c1,vec,beg,end);
+    
+  do {
+    cont_StartBinding();
+    while ((a < end) && 
+	   !unify_Match(cont_LeftContext(),
+			clause_GetLiteralTerm(c1,top_index),
+			clause_GetLiteralTerm(c1,(int)vec_GetNth(a)))) {
+      a++;
+      cont_BackTrackAndStart();
+    }
+    
+    if (a >= end){
+      cont_BackTrack();
+      return FALSE;
+    }
+
+    if ((vec - vec_ActMax()) == 1)
+      return TRUE;		    
+                                    
+    if (subs_InternIdcRes(c1, vec, beg, end))
+      return TRUE;
+    else {
+      cont_BackTrack();	
+      a++;
+    }
+
+  } while (a < end);
+  
+  return FALSE;
+}
+       
+
+static BOOL subs_InternIdcRes(CLAUSE c1, int vec, int beg, int end)
+/**********************************************************
+  INPUT:   A clause c1 and three  vector pointers vec,beg and end.
+  RETURNS: FALSE if the literals of c1 which are designated by
+           the elements of vec do not subsume c2 with respect
+	   to vector and the vector pointers beg and end 
+	   and TRUE otherwise.
+  CAUTION: None.
+***********************************************************/
+{
+  int        locvec;
+  LITPTR litptr;
+  
+  
+  if (!subs_IdcVecTestlitsRes(c1,vec,beg,end,&litptr))
+    return FALSE;
+
+  locvec = vec_ActMax();
+  
+  do {
+    subs_CompVec(litptr);	
+    if (!vec_IsMax(locvec)) {
+      if (!subs_TcVecRes(c1,locvec,beg,end)) {
+	vec_SetMax(locvec);
+	litptr_Delete(litptr);
+	return FALSE;
+      } 
+      else
+	vec_SetMax(locvec);
+    }
+  } while (!litptr_AllUsed(litptr));
+
+  litptr_Delete(litptr);
+  
+  return TRUE;
+}
+
+
+BOOL subs_IdcRes(CLAUSE c1, int beg, int end)
+/**********************************************************
+  INPUT:   A clause c1 and two vector pointers beg and end.
+  RETURNS: FALSE if c1 do not subsume c2 with respect to
+           vector and the vector pointers beg and end
+	   and TRUE otherwise.
+  CAUTION: 
+***********************************************************/
+{
+  int  i,vec;
+  BOOL Result;
+  
+  vec = vec_ActMax();
+  
+  for (i = 0; i < clause_Length(c1); i++)
+    vec_Push((POINTER) i);
+  
+  Result = subs_InternIdcRes(c1, vec, beg, end);
+  
+  vec_SetMax(vec);
+  
+  cont_Reset();
+  
+  return Result;
+}
+
+
+static BOOL subs_TcVecEqExcept(CLAUSE c1, int vec, CLAUSE c2, int i2)
+/**********************************************************
+  INPUT:   Two clauses c1, c2, a vector pointer vec.
+  RETURNS: FALSE if the literals of c1 which are designated by
+           the elements of vec do not subsume c2 and TRUE otherwise.
+  CAUTION: None.
+***********************************************************/
+{
+  int a,top_index;
+  BOOL search;
+  TERM lit1,lit2;
+
+  a         = 0;
+  top_index = subs_SearchTop(c1,vec,c2);
+  lit1      = clause_GetLiteralTerm(c1,top_index);
+    
+  do {
+    search = TRUE;
+
+    while (a < clause_Length(c2) && search) {
+      if (a != i2) {
+	lit2 = clause_GetLiteralTerm(c2,a);
+	cont_StartBinding();
+	if (unify_Match(cont_LeftContext(),lit1,lit2))
+	    search = FALSE;
+	else {
+	  if (symbol_Equal(term_TopSymbol(lit1),term_TopSymbol(lit2)) &&
+	      fol_IsEquality(fol_Atom(lit1)) &&
+	      fol_IsEquality(fol_Atom(lit2)) &&
+	      (clause_LiteralIsNotOrientedEquality(clause_GetLiteral(c1,top_index)) ||
+	       clause_LiteralIsNotOrientedEquality(clause_GetLiteral(c2,a)))) {
+	    cont_BackTrackAndStart();
+	    if (unify_Match(cont_LeftContext(),
+			    term_FirstArgument(fol_Atom(lit1)),
+			    term_SecondArgument(fol_Atom(lit2))) &&
+		unify_Match(cont_LeftContext(),
+			    term_SecondArgument(fol_Atom(lit1)),
+			    term_FirstArgument(fol_Atom(lit2))))
+	      search = FALSE;
+	  }
+	  if (search) {
+	    a++;
+	    cont_BackTrack();
+	  }
+	}
+      }
+      else
+	a++;
+    }
+    
+    if (a>=clause_Length(c2)) {
+      cont_BackTrack();
+      return FALSE;
+    }
+
+    if ((vec_ActMax() - vec) == 1) 
+      return TRUE;		
+    
+    if (subs_InternIdcEqExcept(c1, vec, c2, i2))
+      return TRUE;
+    else {
+      cont_BackTrack();
+      a++;			
+    }
+
+  } while (a < clause_Length(c2));
+  
+  return FALSE;
+}
+
+
+static BOOL subs_SubsumptionVecPossibleEqExcept(CLAUSE c1, int vec,
+						CLAUSE c2, int i2)
+/**********************************************************
+  INPUT:   Two clauses c1 and c2 and a vector pointer
+           and an accept literal index for c2.
+  RETURNS: TRUE if all literals in c1 which indexes stand
+           in the vector with bottom pointer vec can 
+	   independently be matched to a literal in c2.
+  CAUTION: None.
+***********************************************************/
+{
+  int    i,j,n;
+  TERM   lit1,lit2;
+
+  n = clause_Length(c2);
+  for (i = vec; i < vec_ActMax(); i++) {
+    lit1 = clause_GetLiteralTerm(c1, (int) vec_GetNth(i));
+    for (j = 0; j < n; j++) {
+      if (j != i2) { 
+	lit2 = clause_GetLiteralTerm(c2,j);
+	cont_StartBinding();
+	if (unify_Match(cont_LeftContext(),lit1,lit2))
+	  j = n + 1;
+	else {
+	  if (symbol_Equal(term_TopSymbol(lit1),term_TopSymbol(lit2)) &&
+	      fol_IsEquality(fol_Atom(lit1)) &&
+	      fol_IsEquality(fol_Atom(lit2)) &&
+	      (clause_LiteralIsNotOrientedEquality(
+                 clause_GetLiteral(c1,(int)vec_GetNth(i))) ||
+	       clause_LiteralIsNotOrientedEquality(clause_GetLiteral(c2,j)))) {
+	    cont_BackTrackAndStart();
+	    if (unify_Match(cont_LeftContext(),
+			    term_FirstArgument(fol_Atom(lit1)),
+			    term_SecondArgument(fol_Atom(lit2))) &&
+		unify_Match(cont_LeftContext(),
+			    term_SecondArgument(fol_Atom(lit1)),
+			    term_FirstArgument(fol_Atom(lit2))))
+	      j = n+1;
+	  }
+	}
+	cont_BackTrack();
+      }
+    }
+    if (j==n)
+      return FALSE;
+  }
+  
+  return TRUE;
+}
+
+
+static BOOL subs_IdcVecTestlitsEqExcept(CLAUSE c1, int vec,
+					CLAUSE c2, int i2, LITPTR* litptr)
+/**********************************************************
+  INPUT:   Two clauses c1, c2, a pointer to a literal structure and
+           a vector pointer and a literal index i2 in c2
+  RETURNS: FALSE if the literals of c1 which are designated by
+           the elements of vec do not subsume c2 and TRUE otherwise.
+  CAUTION: A structure is build and litptr points to that structure.
+  ***********************************************************/
+{
+  LIST  TermIndexlist,VarSymbList,TermSymbList;
+  int   i;
+  
+  if (subs_SubsumptionVecPossibleEqExcept(c1,vec,c2,i2)) {
+    
+    TermIndexlist  = list_Nil();
+    VarSymbList    = list_Nil();
+    TermSymbList   = list_Nil();
+    
+    for (i = vec; i < vec_ActMax(); i++) {
+      VarSymbList =
+	subs_GetVariables(clause_GetLiteralTerm(c1, (int) vec_GetNth(i)));
+   
+      if (VarSymbList != list_Nil()){
+	TermIndexlist = list_Cons(vec_GetNth(i), TermIndexlist);         
+	TermSymbList  = list_Cons(VarSymbList,TermSymbList);
+      } 
+    }
+	    
+    *litptr = litptr_Create(TermIndexlist,TermSymbList); 
+
+    list_Delete(TermSymbList);
+    list_Delete(TermIndexlist);
+	
+    return TRUE;
+  }
+  return FALSE;
+}
+
+
+static BOOL subs_InternIdcEqExcept(CLAUSE c1, int vec, CLAUSE c2, int i2)
+/**********************************************************
+  INPUT:   Two clauses c1, c2, a vector pointer vec and a literal
+           i2 in c2 which must not be considered
+  RETURNS: FALSE if the literals of c1 which are designed by
+           the elements of vec do not subsume c2/i2 and TRUE otherwise.
+  CAUTION: 
+***********************************************************/
+{
+  int        locvec;
+  LITPTR litptr;
+  
+  
+  if (!subs_IdcVecTestlitsEqExcept(c1,vec,c2,i2,&litptr))
+    return FALSE;
+
+  locvec = vec_ActMax();
+  
+  do {
+    subs_CompVec(litptr);	
+    if (!vec_IsMax(locvec)) {
+      if (!subs_TcVecEqExcept(c1,locvec,c2,i2)) {
+	vec_SetMax(locvec);
+	litptr_Delete(litptr);
+	return FALSE;
+      } 
+      else
+	vec_SetMax(locvec);
+    }
+  } while (!litptr_AllUsed(litptr));
+
+  litptr_Delete(litptr);
+  
+  return TRUE;
+}
+
+
+BOOL subs_IdcEqMatchExcept(CLAUSE c1, int i1, CLAUSE c2, int i2,
+				  SUBST subst)
+/**********************************************************
+  INPUT:   Two clauses c1, c2 with the indices of two literals
+           which need not to be considered and a matcher
+  RETURNS: TRUE if (<c1>/<i1>)<subst> subsumes (<c2>/<i2>)<subst>
+  CAUTION: 
+***********************************************************/
+{
+  int  i,vec;
+  BOOL Result;
+
+  /*fputs("\n IdcEQExcept on:  \n\t", stdout);
+    subst_Print(subst); fputs("\n\t", stdout);
+    clause_Print(c1); printf(" \t\t%d \n\t",i1); 
+    clause_Print(c2);  printf(" \t\t%d \n\t",i2);*/
+
+  if (clause_Length(c1) == 1)
+    Result = TRUE;
+  else {
+    vec = vec_ActMax();
+
+    for (i = 0; i < clause_Length(c1); i++)
+      if (i != i1)
+	vec_Push((POINTER) i);
+
+    i = 0;    /* Doesn't matter, there is a general cont_Reset below */
+    unify_EstablishMatcher(cont_LeftContext(), subst);
+
+    Result = subs_InternIdcEqExcept(c1,vec,c2,i2);
+
+    /* printf("Result : %d",Result); */
+
+    vec_SetMax(vec);
+
+    cont_Reset();
+  }
+
+  return Result;
+}
diff --git a/test/spass/subsumption.h b/test/spass/subsumption.h
new file mode 100644
index 0000000000000000000000000000000000000000..3f5b8ab75f247f2ac0fcb91773b9e83ccc34a637
--- /dev/null
+++ b/test/spass/subsumption.h
@@ -0,0 +1,87 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                     SUBSUMPTION                        * */
+/* *                                                        * */
+/* *  $Module:   SUBSUMPTION                                * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1999, 2000                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#ifndef _SUBSUMPTION_
+#define _SUBSUMPTION_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "misc.h"
+#include "unify.h"
+#include "component.h"
+#include "vector.h"
+#include "clause.h"
+
+/**************************************************************/
+/* Functions                                                 */
+/**************************************************************/
+
+#define subs__MAXLITS 100
+
+static __inline__ int subs_NoException(void)
+{
+  return -1;
+}
+
+void subs_Init(void);
+BOOL subs_ST(int, int, CLAUSE, CLAUSE);
+BOOL subs_STMulti(CLAUSE, CLAUSE);
+BOOL subs_STMultiExcept(CLAUSE, CLAUSE, int, int);
+BOOL subs_Subsumes(CLAUSE, CLAUSE, int, int);
+BOOL subs_SubsumesBasic(CLAUSE, CLAUSE, int, int);
+BOOL subs_SubsumesWithSignature(CLAUSE, CLAUSE, BOOL, LIST*);
+BOOL subs_Idc(CLAUSE, CLAUSE);
+BOOL subs_IdcRes(CLAUSE, int, int);
+BOOL subs_IdcEq(CLAUSE, CLAUSE);
+BOOL subs_IdcEqMatch(CLAUSE, CLAUSE, SUBST);
+BOOL subs_IdcEqMatchExcept(CLAUSE, int, CLAUSE, int, SUBST);
+
+#endif
+
diff --git a/test/spass/symbol.c b/test/spass/symbol.c
new file mode 100644
index 0000000000000000000000000000000000000000..ab1b0b450dd2c1edd3c776b77ee60fe2ed51a850
--- /dev/null
+++ b/test/spass/symbol.c
@@ -0,0 +1,1020 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                     SYMBOLS                            * */
+/* *                                                        * */
+/* *  $Module:   SYMBOL                                     * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "symbol.h"
+
+SIGNATURE *symbol_SIGNATURE;
+
+SYMBOL symbol_STANDARDVARCOUNTER;
+SYMBOL symbol_INDEXVARCOUNTER;
+
+const int symbol_MASK         = 3;  /* 0000011 */
+const int symbol_TYPEMASK     = 3;  /* 0000011 */
+const int symbol_STATMASK     = 4;  /* 0000100 */
+const int symbol_TYPESTATMASK = 7;  /* 0000111 */
+
+
+const int symbol_TYPEBITS      = 2;
+const int symbol_STATBITS      = 1;
+const int symbol_TYPESTATBITS  = 3;
+
+const int symbol_SIGTYPES = 4;
+
+const char symbol_SKFNAME[]="skf";
+const char symbol_SKCNAME[]="skc";
+const char symbol_SKPNAME[]="SkP";
+const char symbol_SKANAME[]="SkC";
+const int  symbol_SKLENGTH = 3;
+
+static BOOL symbol_HASSIGNATURE;
+static LIST symbol_FREEDSYMBOLS;
+
+int  symbol_ACTINDEX;
+int  symbol_ACTSKOLEMFINDEX;
+int  symbol_ACTSKOLEMCINDEX;
+int  symbol_ACTSKOLEMAINDEX;
+int  symbol_ACTSKOLEMPINDEX;
+int  symbol_ORDERING;
+char *symbol_VARSTRING;
+
+SYMBOL symbol_CONTEXT[symbol__MAXSIGNATURE];
+
+static unsigned long symbol_COUNT[symbol__MAXSIGNATURE];
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  SYMBOL CREATION                                       * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+int symbol_GetIncreasedOrderingCounter(void)
+{
+  return symbol_ORDERING++;
+}
+
+NAT symbol_MaxStringLength(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: The maximal number of characters needed for a string in the signature.
+***************************************************************/
+{
+  int       Index;
+  NAT       Result,Length;
+  SIGNATURE Entry;
+
+  Result = 0;
+  
+  for (Index=1; Index < symbol_ACTINDEX; Index++) {
+    Entry = symbol_Signature(Index);
+    if (Entry != NULL) {
+      Length = Entry->length;
+      if (Length > Result)
+	Result = Length;
+    }
+  }
+  return Result;
+}
+
+static SYMBOL symbol_SignatureCreate(char* String, int Type, int Arity,
+				     int Status, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A pointer to a string, a type, the arity and the status
+  RETURNS: The symbol containing the passed parameters.
+  SUMMARY: Establishes a new symbol in the symbol table and returns the
+	   internal representation (pointer and type).
+  CAUTION: The string is not copied!
+***************************************************************/
+{
+  SIGNATURE Entry;
+  
+#ifdef CHECK
+  if (!symbol_SignatureExists()) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In symbol_SignatureCreate:");
+    misc_ErrorReport(" Module was initialized with no signature.\n");
+    misc_FinishErrorReport();
+  } 
+  if (Type < 0 || Type >= symbol_SIGTYPES) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In symbol_SignatureCreate: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if ((int)symbol_ACTINDEX >= symbol__MAXSIGNATURE &&
+      list_Empty(symbol_FREEDSYMBOLS)) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n In symbol_SignatureCreate: No more symbols available.\n");
+    misc_FinishUserErrorReport();
+  }
+  
+  if (strlen(String)>=symbol__SYMBOLMAXLEN) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n In symbol_SignatureCreate: String too long.\n");
+    misc_FinishUserErrorReport();
+  }
+    
+  Entry              = symbol_GetSignature();
+  Entry->weight      = 1;
+  Entry->props       = 0;
+  Entry->name        = String;
+  Entry->length      = strlen(String);
+  Entry->arity       = Arity;
+  Entry->generatedBy = list_Nil();
+  
+  if (list_Empty(symbol_FREEDSYMBOLS)) {
+    Entry->info = symbol_SignatureSymbol(symbol_ACTINDEX, Type, Status);
+    symbol_SetSignature(symbol_ACTINDEX++, Entry);
+  }
+  else {
+    int Index;
+    
+    Index               = (int)list_Car(symbol_FREEDSYMBOLS);
+    symbol_FREEDSYMBOLS = list_PointerDeleteElement(symbol_FREEDSYMBOLS,
+						    (POINTER)Index);
+    Entry->info = symbol_SignatureSymbol(Index, Type, Status);
+    symbol_SetSignature(Index, Entry);
+  }
+
+  /* Define precedence of symbol */
+  symbol_SetIncreasedOrdering(Precedence, Entry->info);
+
+  return Entry->info;
+}
+
+
+SYMBOL symbol_CreateFunction(const char* String, int Arity, int Status,
+			     PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A string defining a symbol name, an arity, the status the 
+           created function symbol is supposed to have and a precedence
+	   object.
+  RETURNS: A new symbol for a new function.
+  SUMMARY: Creates a new function symbol.
+  EFFECTS: Inserts the new function in the symbol table.
+           The precedence of the new symbol is set in <Precedence>.
+***************************************************************/
+{
+  if (Arity == 0)
+    return symbol_SignatureCreate(strcpy(memory_Malloc(symbol__SYMBOLMAXLEN),
+					 String),
+				  symbol_CONSTANT, Arity, Status, Precedence);
+  else
+    return symbol_SignatureCreate(strcpy(memory_Malloc(symbol__SYMBOLMAXLEN),
+					 String),
+				  symbol_FUNCTION, Arity, Status, Precedence);
+}
+
+SYMBOL symbol_CreateSkolemFunction(int Arity, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   The arity of a function to be created, and a precedence.
+  RETURNS: A new skolem symbol having the required arity.
+  SUMMARY: Creates a new function symbol.
+  EFFECTS: Inserts the new function in the symbol table.
+           The precedence of the new symbol is set in <Precedence>.
+***************************************************************/
+{
+  char   newname[10];
+  SYMBOL Result;
+
+  Result = (SYMBOL)NULL;
+
+  while (Result == (SYMBOL)NULL) {
+    if (Arity == 0)
+      sprintf(newname,"%s%d",symbol_SKCNAME,symbol_ACTSKOLEMCINDEX++);
+    else
+      sprintf(newname,"%s%d",symbol_SKFNAME,symbol_ACTSKOLEMFINDEX++);
+    if (symbol_Lookup(newname) == 0)
+      Result = symbol_CreateFunction(newname, Arity, symbol_STATLEX, Precedence);
+  }
+
+  symbol_AddProperty(Result,SKOLEM);
+
+  return Result;
+}
+
+
+SYMBOL symbol_CreatePredicate(const char* String, int Arity, int Status,
+			      PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A string, a symbol arity, the status the created predicate
+           is supposed to have, and a precedence object.
+  RETURNS: A new symbol for a new predicate.
+  SUMMARY: Creates a new predicate symbol.
+  EFFECTS: Inserts the new predicate symbol into the symbol table.
+           The precedence of the new symbol is set in <Precedence>.
+***************************************************************/
+{ 
+  return symbol_SignatureCreate(strcpy(memory_Malloc(symbol__SYMBOLMAXLEN),
+				       String),
+				symbol_PREDICATE, Arity, Status, Precedence);
+}
+
+SYMBOL symbol_CreateSkolemPredicate(int Arity, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   The arity of a new Skolem predicate symbol and a precedence object.
+  RETURNS: A new symbol for a new predicate.
+  SUMMARY: Creates a new predicate symbol.
+  EFFECTS: Inserts the new predicate symbol into the symbol table.
+           The precedence of the new symbol is set in <Precedence>.
+***************************************************************/
+{ 
+  char   newname[10];
+  SYMBOL Result;
+
+  Result = (SYMBOL)NULL;
+
+  while (Result == (SYMBOL)NULL) {
+    if (Arity==0)
+      sprintf(newname,"%s%d",symbol_SKANAME,symbol_ACTSKOLEMAINDEX++);
+    else
+      sprintf(newname,"%s%d",symbol_SKPNAME,symbol_ACTSKOLEMPINDEX++);
+    if (symbol_Lookup(newname) == 0)
+      Result = symbol_CreatePredicate(newname, Arity, symbol_STATLEX, Precedence);
+  }
+
+  return Result;
+}
+
+
+SYMBOL symbol_CreateJunctor(const char* String, int Arity, int Status,
+			    PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A string, a symbol arity, the status the created junctor
+           is supposed to have, and a precedence object.
+  RETURNS: A new symbol for a new junctor.
+  SUMMARY: Creates a new junctor symbol.
+  EFFECTS: Inserts the new junctor symbol into the symbol table.
+           The precedence of the new symbol is set in <Precedence>.
+***************************************************************/
+{ 
+  return symbol_SignatureCreate(strcpy(memory_Malloc(symbol__SYMBOLMAXLEN),
+				       String),
+				symbol_JUNCTOR, Arity, Status, Precedence);
+}
+
+
+BOOL symbol_IsSymbol(SYMBOL Symbol)
+/**************************************************************
+  INPUT:    A symbol.
+  RETURNS: TRUE if the symbols is  a variable or contained
+           in the symbol table.
+***************************************************************/
+{
+  return 
+    (!symbol_SignatureExists() ||
+     ((!symbol_Equal(Symbol, symbol__NULL)) &&
+      ((symbol_IsVariable(Symbol) && Symbol<symbol_MaxVars()) || 
+       (symbol_IsSignature(Symbol) && symbol_Index(Symbol)<symbol_ACTINDEX))));
+}
+
+
+void symbol_Delete(SYMBOL Symbol)
+/**************************************************************
+  INPUT:   A symbol.
+  RETURNS: Nothing.
+  SUMMARY: Deletes the symbol from the symbol table and frees its memory.
+***************************************************************/
+{
+#ifdef CHECK
+  if (!symbol_SignatureExists()) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In symbol_Delete: Module was initialized without signature.\n");
+    misc_FinishErrorReport();
+  }
+  if (!symbol_IsSymbol(Symbol)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In symbol_Delete: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (!symbol_IsVariable(Symbol)) {
+    int       Index;
+    SIGNATURE Entry;
+    
+    Index               = symbol_Index(Symbol);
+    symbol_FREEDSYMBOLS = list_Cons((POINTER)Index,symbol_FREEDSYMBOLS);
+    Entry               = symbol_Signature(Index);
+    symbol_SetSignature(Index, NULL);
+    symbol_FreeSignature(Entry);
+  }
+}
+
+LIST symbol_GetAllSymbols(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: A list of all generated symbols.
+***************************************************************/
+{
+  LIST Result;
+
+  Result = list_Nil();
+
+  if (symbol_SignatureExists()) {
+    int       Index;
+    SIGNATURE S;
+    
+    for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+      S = symbol_Signature(Index);
+      if (S != NULL) {
+	Result = list_Cons((POINTER)symbol_GetSigSymbol(Index), Result);
+      }
+    }
+  }
+  return Result;
+}
+
+
+LIST symbol_GetAllPredicates(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: A list of all predicate symbols.
+***************************************************************/
+{
+  LIST Result;
+
+  Result = list_Nil();
+
+  if (symbol_SignatureExists()) {
+    int       Index;
+    SIGNATURE S;
+    
+    for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+      S = symbol_Signature(Index);
+      if (S != NULL && symbol_IsPredicate(symbol_GetSigSymbol(Index)))
+	Result = list_Cons((POINTER)symbol_GetSigSymbol(Index), Result);
+    }
+  }
+  return Result;
+}
+
+
+LIST symbol_GetAllFunctions(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: A list of all function symbols.
+***************************************************************/
+{
+  LIST Result;
+
+  Result = list_Nil();
+
+  if (symbol_SignatureExists()) {
+    int       Index;
+    SIGNATURE S;
+    
+    for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+      S = symbol_Signature(Index);
+      if (S != NULL && symbol_IsFunction(symbol_GetSigSymbol(Index)))
+	Result = list_Cons((POINTER)symbol_GetSigSymbol(Index), Result);
+    }
+  }
+  return Result;
+}
+
+
+void symbol_FreeAllSymbols(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: Nothing.
+  EFFECTS: Frees all generated symbols
+***************************************************************/
+{
+  if (symbol_SignatureExists()) {
+    int       Index;
+    SIGNATURE S;
+    
+    for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+      S = symbol_Signature(Index);
+      if (S != NULL)
+	symbol_FreeSignature(S);
+    }
+    memory_Free(symbol_SIGNATURE, sizeof(SIGNATURE[symbol__MAXSIGNATURE]));
+  }
+  
+  memory_Free(symbol_VARSTRING, symbol__SYMBOLMAXLEN);
+  list_Delete(symbol_FREEDSYMBOLS);
+}
+
+
+void symbol_Init(BOOL Signature)
+/**************************************************************
+  INPUT:   A flag indicating whether a signature is used or not.
+  RETURNS: None.
+  SUMMARY: Initializes the Symbol Module.
+  EFFECTS: Initializes global variables.
+  CAUTION: MUST BE CALLED BEFORE ANY OTHER Symbol-FUNCTION.
+***************************************************************/
+{
+  symbol_ResetSkolemIndex();
+  symbol_ContextClean();
+
+  if (Signature)
+    symbol_SIGNATURE = (SIGNATURE*)memory_Malloc(sizeof(SIGNATURE[symbol__MAXSIGNATURE]));
+
+  symbol_STANDARDVARCOUNTER = symbol_GetInitialStandardVarCounter();
+  symbol_INDEXVARCOUNTER    = symbol_GetInitialIndexVarCounter();
+  
+  symbol_ACTINDEX           = 1;
+  symbol_ORDERING           = 1;
+  symbol_VARSTRING          = memory_Malloc(symbol__SYMBOLMAXLEN);
+  
+  symbol_HASSIGNATURE       = Signature;
+  symbol_FREEDSYMBOLS       = list_Nil();
+}
+
+
+BOOL symbol_SignatureExists(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: TRUE, if a symbol signature was created, FALSE otherwise.
+***************************************************************/
+{
+  return symbol_HASSIGNATURE;
+}
+
+void symbol_ReinitGenericNameCounters(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: Nothing.
+  EFFECTS: Scans the symbol signature for generic names and if
+           there exists some, the corresponding counters are increased.
+***************************************************************/
+{
+  if (symbol_SignatureExists()) {
+    int          Index,Num;
+    SYMBOL       Info;
+    SIGNATURE    Entry;
+    char         *Name,*Subname;
+  
+    for (Index=1; Index < symbol_ACTINDEX; Index++) {
+      Entry = symbol_Signature(Index);
+      if (Entry != NULL) {
+	Info   = Entry->info;
+	Name   = Entry->name;
+	if (strlen(Name)>symbol_SKLENGTH) {
+	  Subname = Name + symbol_SKLENGTH;
+	
+	  switch (symbol_Type(Info)) {
+	  
+	  case symbol_CONSTANT:
+	    if (strncmp(Name,symbol_SKCNAME,symbol_SKLENGTH) == 0 && 
+		string_StringIsNumber(Subname)) {
+	      Num = atoi(Subname);
+	      if (Num >= symbol_ACTSKOLEMCINDEX)
+		symbol_ACTSKOLEMCINDEX = Num + 1;
+	    }
+	    break;
+	  case symbol_FUNCTION:
+	    if (strncmp(Name,symbol_SKFNAME,symbol_SKLENGTH) == 0  &&
+		string_StringIsNumber(Subname)) {
+	      Num = atoi(Subname);
+	      if (Num >= symbol_ACTSKOLEMFINDEX)
+		symbol_ACTSKOLEMFINDEX = Num + 1;
+	    }
+	    break;
+	  case symbol_PREDICATE:
+	    if (Entry->arity == 0) {
+	      if (strncmp(Name,symbol_SKANAME,symbol_SKLENGTH) == 0  &&
+		  string_StringIsNumber(Subname)) {
+		Num = atoi(Subname);
+		if (Num >= symbol_ACTSKOLEMAINDEX)
+		  symbol_ACTSKOLEMAINDEX = Num + 1;
+	      }
+	    }
+	    else {
+	      if (strncmp(Name,symbol_SKPNAME,symbol_SKLENGTH) == 0  &&
+		  string_StringIsNumber(Subname)) {
+		Num = atoi(Subname);
+		if (Num >= symbol_ACTSKOLEMPINDEX)
+		  symbol_ACTSKOLEMPINDEX = Num + 1;
+	      }
+	    }    
+	  }
+	}
+      }
+    }
+  }
+}
+
+  
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  SYMBOL SEARCHING                                      * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+SYMBOL symbol_Lookup(const char* String)
+/**********************************************************
+  INPUT:   A pointer to a string.
+  RETURNS: If a symbol with name String exists in the signature, the symbol;
+           0 otherwise
+********************************************************/
+{
+  if (symbol_SignatureExists()) {
+    int       Index;
+    SIGNATURE S;
+    
+    for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+      S = symbol_Signature(Index);
+      if (S != NULL && string_Equal(String, S->name))
+	return S->info;
+    }
+  }
+  
+  return 0;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  SPECIALS                                              * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+void symbol_LowerSignature(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: Nothing.
+  EFFECT:  Any predicate or function symbol in the signature that
+           starts with a capital letter is prefixed with "ss"
+***************************************************************/
+{
+  int       Index;
+  SIGNATURE Entry;
+  SYMBOL    Info;
+  char*     String;
+
+  for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+    Entry = symbol_Signature(Index);
+    if (Entry != NULL) {
+      Info = Entry->info;
+	
+      if (symbol_IsPredicate(Info) || symbol_IsFunction(Info)) {
+	String = Entry->name;
+	if ('A' <= String[0] && String[0] <= 'Z') {
+	  char* New;
+	  New = (char *)memory_Malloc(symbol__SYMBOLMAXLEN);
+	  strcpy(&(New[2]),String);
+	  New[0] = New[1] = 's';             /* prefix "ss" */
+
+	  Entry->name = New;
+	  memory_Free(String,symbol__SYMBOLMAXLEN);
+	}
+      }
+    }
+  }
+}
+
+void symbol_Dump(PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A precedence
+  RETURNS: Nothing.
+  EFFECT:  Dumps all existing symbols to stdout.
+***************************************************************/
+{
+  if (symbol_SignatureExists()) {
+    int       Index;
+    SIGNATURE S;
+    fputs("Dump:", stdout);
+    for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+      S = symbol_Signature(Index);
+      if (S != NULL)
+	printf("\n\t %4d:%4d:%4d:%4d:%4d:%s:%d", Index, S->info, S->weight,
+	       Precedence[Index], S->props, S->name, S->length);
+    }
+  }
+}
+
+
+LIST symbol_SortByPrecedence(LIST Symbols, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A list of symbols, and a precedence.
+  RETURNS: The same list where the elements are sorted with
+           respect to decreasing precedence.
+  CAUTION: Destructive.
+***************************************************************/
+{
+  LIST Scan1,Scan2,Min;
+  POINTER Exchange;
+
+  /* We can't use list_Sort, since list_Sort expects an ordering
+     function that receives two arguments. Since symbol_PrecedenceGreater
+     requires three arguments, we have to define our own sorting function.
+  */
+
+  for (Scan1=Symbols; !list_Empty(Scan1); Scan1=list_Cdr(Scan1)) {
+    Min = Scan1;
+    for (Scan2 = list_Cdr(Scan1); !list_Empty(Scan2); Scan2 = list_Cdr(Scan2))
+      if (symbol_PrecedenceGreater(Precedence, (SYMBOL) list_Car(Scan2),
+				   (SYMBOL) list_Car(Min))) {
+	Exchange = list_Car(Min);
+	list_Rplaca(Min, list_Car(Scan2));
+	list_Rplaca(Scan2, Exchange);
+      }
+  }
+
+  return Symbols;
+}
+
+void symbol_RearrangePrecedence(PRECEDENCE Precedence, LIST UserPrecedence)
+/**************************************************************
+  INPUT:   A precedence and a list of symbols in the user 
+           specified precedence, sorted in decreasing order.
+  RETURNS: Nothing.
+  EFFECT:  Modifies the given precedence to comply with the
+           symbol precedence selected by the user.
+***************************************************************/
+{
+  LIST Scan1, Scan2, Precedences;
+
+  Precedences = list_Nil();
+
+  for (Scan1 = UserPrecedence; !list_Empty(Scan1); Scan1 = list_Cdr(Scan1)) {
+    Precedences = list_Cons((POINTER) symbol_Ordering(Precedence, (SYMBOL) list_Car(Scan1)), 
+			    Precedences);
+  }
+
+  Precedences = list_PointerSort(Precedences);
+
+  Scan1 = UserPrecedence;
+  Scan2 = Precedences;
+
+  while (Scan1 != list_Nil() && Scan2 != list_Nil()) {
+    symbol_SetOrdering(Precedence, (SYMBOL) list_Car(Scan1), (int) list_Car(Scan2));
+    Scan1 = list_Cdr(Scan1);
+    Scan2 = list_Cdr(Scan2);
+  }
+
+  list_Delete(Precedences);
+}
+  
+/* unused */
+void symbol_PrintPrecedence(PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A precedence.
+  RETURNS: Nothing.
+  EFFECT:  Prints the precedence to stdout.
+***************************************************************/
+{
+  if (symbol_SignatureExists()) {
+    LIST      Symbols, Scan;
+    int       Index;
+    SIGNATURE S;
+    Symbols = list_Nil();
+    for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+      S = symbol_Signature(Index);
+      if (S != NULL &&
+	  (symbol_IsPredicate(S->info) || symbol_IsFunction(S->info))) 
+	Symbols = list_Cons((POINTER)S->info, Symbols);
+    }
+    Symbols = symbol_SortByPrecedence(Symbols, Precedence);
+
+    for (Scan = Symbols; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+      S = symbol_Signature(symbol_Index((SYMBOL)list_Car(Scan)));
+      fputs(S->name, stdout);
+      if (!list_Empty(list_Cdr(Scan)))
+	fputs(" > ", stdout);
+    }
+    list_Delete(Symbols);
+  }
+}
+
+
+void symbol_FPrintPrecedence(FILE *File, PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A file pointer and a precedence.
+  RETURNS: void
+  EFFECT:  Prints the current precedence as a setting command
+           in DFG syntax to <File>.
+***************************************************************/
+{
+  if (symbol_SignatureExists()) {
+    LIST Symbols,Scan;
+    int Index;
+    SIGNATURE S;
+
+    Symbols = list_Nil();
+    for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+      S = symbol_Signature(Index);
+      if (S != NULL &&
+	  (symbol_IsPredicate(S->info) || symbol_IsFunction(S->info))) 
+	Symbols = list_Cons((POINTER)S->info, Symbols);
+    }
+    Symbols = symbol_SortByPrecedence(Symbols, Precedence);
+    Index   = 0;
+    fputs("set_precedence(", File);
+    for (Scan = Symbols; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+      S = symbol_Signature(symbol_Index((SYMBOL)list_Car(Scan)));
+      fputs(S->name, File);
+      if (!list_Empty(list_Cdr(Scan)))
+	putc(',', File);
+      if (Index > 15) {
+	Index = 0;
+	fputs("\n\t", File);
+      }
+      else
+	Index++;
+    }
+    fputs(").", File);
+    list_Delete(Symbols);
+  }
+}
+
+void symbol_SetCount(SYMBOL Symbol, unsigned long Count)
+/**************************************************************
+  INPUT:   A symbol, and a symbol count.
+  RETURNS: Nothing.
+  SUMMARY: Sets the symbol count for the symbol to Count. 
+***************************************************************/
+{
+  symbol_COUNT[symbol_Index(Symbol)] = Count;
+}
+
+unsigned long symbol_GetCount(SYMBOL Symbol)
+/**************************************************************
+  INPUT:   A symbol.
+  RETURNS: The number of occurences of the symbol in the clause
+           set.
+  SUMMARY: Gets the symbol count for the symbol. 
+***************************************************************/
+{
+  return symbol_COUNT[symbol_Index(Symbol)];
+}
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  SYMBOL OUTPUT	                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+void symbol_Print(SYMBOL Symbol)
+/**************************************************************
+  INPUT:   A symbol.
+  RETURNS: Nothing.
+  SUMMARY: Prints a symbol to stdout. 
+***************************************************************/
+{
+  symbol_FPrint(stdout, Symbol);
+}
+
+
+void symbol_FPrint(FILE* File, SYMBOL Symbol)
+/**************************************************************
+  INPUT:   A file and a symbol.
+  RETURNS: None.
+  SUMMARY: Prints a symbol to the file. 
+***************************************************************/
+{ 
+#ifdef CHECK
+  if (!symbol_IsSymbol(Symbol)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In symbol_FPrint: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (symbol_Equal(symbol_Null(),Symbol))
+    fputs("NULL", File);
+  else if (symbol_IsVariable(Symbol)) {
+    SYMBOL NormSymbol;
+
+    NormSymbol = symbol_NormVar(Symbol);
+
+    if (symbol_IsStandardVariable(Symbol)) {
+      if (Symbol <= 6)
+	/* U, V, W, X, Y, Z */
+	sprintf(symbol_VARSTRING,"%c", 'U' + NormSymbol - 1);
+      else
+	/* X1, X2, X3, ... */
+	sprintf(symbol_VARSTRING,"X%d", NormSymbol - 6);
+    }
+    else if (symbol_IsIndexVariable(Symbol))
+      /* I1, I2, I3, ... */
+      sprintf(symbol_VARSTRING,"I%d", NormSymbol);
+
+    fputs(symbol_VARSTRING, File);
+  }
+  else if (symbol_SignatureExists())
+    fputs(symbol_Name(Symbol), File);
+  else
+    fprintf(File, "%d", Symbol);
+}
+
+
+void symbol_FPrintOtter(FILE* File, SYMBOL Symbol)
+/**************************************************************
+  INPUT:   A file and a symbol.
+  RETURNS: None.
+  SUMMARY: Prints a symbol in Otter format to stdout. 
+***************************************************************/
+{ 
+#ifdef CHECK
+  if (!symbol_IsSymbol(Symbol)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In symbol_FPrintOtter: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (symbol_IsVariable(Symbol)) {
+    SYMBOL NormSymbol;
+
+    NormSymbol = symbol_NormVar(Symbol);
+
+    if (symbol_IsStandardVariable(Symbol)) {
+      if (Symbol <= 6)
+	/* u, v, w, x, y, z */
+	sprintf(symbol_VARSTRING,"%c", 116 + NormSymbol);
+      else
+	/* x1, x2, x3, ... */
+	sprintf(symbol_VARSTRING,"x%d", NormSymbol - 6);
+    }
+    else if (symbol_IsIndexVariable(Symbol))
+      /* I1, I2, I3, ... */
+      sprintf(symbol_VARSTRING,"I%d", NormSymbol);
+
+    fputs(symbol_VARSTRING, File);
+  }
+  else 
+    if (symbol_SignatureExists()) {
+      if (symbol_IsConstant(Symbol))
+	fprintf(File, "c%s", symbol_Name(Symbol));
+      else
+	if (symbol_IsFunction(Symbol))
+	  fprintf(File, "f%s", symbol_Name(Symbol));
+	else
+	  if (symbol_IsPredicate(Symbol))
+	    fprintf(File, "P%s", symbol_Name(Symbol));
+	  else
+	    fputs(symbol_Name(Symbol), File);
+    }
+    else
+      fprintf(File, "%d", Symbol);
+}
+
+
+void symbol_PrintLn(SYMBOL Symbol)
+/**************************************************************
+  INPUT:   A symbol.
+  RETURNS: None.
+  SUMMARY: Prints a symbol and a newline to stdout. 
+***************************************************************/
+{ 
+  symbol_Print(Symbol);
+  putchar('\n');
+  
+}
+
+
+void symbol_PrintAll(void)
+/**************************************************************
+  INPUT:   None.
+  RETURNS: None.
+  SUMMARY: Prints all symbols to stdout.
+***************************************************************/
+{
+  const int symbol_TABLEBLANKS = 2;
+  const int symbol_TABLETYPE   = 6;  /* breadth of the columns */
+  const int symbol_TABLEARITY  = 7;
+  const int symbol_TABLESTAT   = 6;
+  const int symbol_TABLEPROP   = 8;  
+  const int symbol_TABLESTRING = 36;
+
+  if (symbol_SignatureExists()) {
+    int          Index;
+    SYMBOL       Info;
+    SIGNATURE    Entry;
+    unsigned int TypePos, ArityPos, StatPos, PropPos, StringPos, EndPos, ActPos;
+
+    TypePos   = symbol_TABLEBLANKS;
+    ArityPos  = TypePos   + symbol_TABLETYPE   + 1;
+    StatPos   = ArityPos  + symbol_TABLEARITY  + 1;
+    PropPos   = StatPos   + symbol_TABLESTAT   + 1;
+    StringPos = PropPos   + symbol_TABLEPROP   + 1;
+    EndPos    = StringPos + symbol_TABLESTRING + 1;
+
+    fputs("\n\n", stdout);
+    misc_PrintChar(symbol_TABLEBLANKS, ' '); putchar('+');
+    misc_PrintChar(symbol_TABLETYPE,   '-'); putchar('+');
+    misc_PrintChar(symbol_TABLEARITY,  '-'); putchar('+');
+    misc_PrintChar(symbol_TABLESTAT,   '-'); putchar('+');
+    misc_PrintChar(symbol_TABLEPROP,   '-'); putchar('+');
+    misc_PrintChar(symbol_TABLESTRING, '-'); putchar('+'); putchar('\n');
+    misc_PrintChar(symbol_TABLEBLANKS, ' '); putchar('|');
+    ActPos = TypePos   + 1 + fputs(" Type", stdout);
+    misc_PrintChar((ArityPos  - ActPos), ' '); putchar('|');
+    ActPos = ArityPos  + 1 + fputs(" Arity", stdout);
+    misc_PrintChar((StatPos   - ActPos), ' '); putchar('|');
+    ActPos = StatPos   + 1 + fputs(" Stat", stdout);
+    misc_PrintChar((PropPos   - ActPos), ' '); putchar('|');
+    ActPos = PropPos   + 1 + fputs(" Prop", stdout);
+    misc_PrintChar((StringPos - ActPos), ' '); putchar('|');
+    ActPos = StringPos + 1 + fputs(" String", stdout);
+    misc_PrintChar((EndPos    - ActPos), ' '); putchar('|'); putchar('\n');
+    misc_PrintChar(symbol_TABLEBLANKS,   ' '); putchar('+');
+    misc_PrintChar(symbol_TABLETYPE,     '-'); putchar('+');
+    misc_PrintChar(symbol_TABLEARITY,    '-'); putchar('+');
+    misc_PrintChar(symbol_TABLESTAT,     '-'); putchar('+');
+    misc_PrintChar(symbol_TABLEPROP,     '-'); putchar('+');
+    misc_PrintChar(symbol_TABLESTRING,   '-'); putchar('+'); putchar('\n');
+  
+    for (Index = 1; Index < symbol_ACTINDEX; Index++) {
+      Entry  = symbol_Signature(Index);
+      if (Entry != NULL) {
+	Info = Entry->info;
+	
+	misc_PrintChar(symbol_TABLEBLANKS,   ' '); putchar('|');
+	ActPos = TypePos + 1;
+
+	switch (symbol_Type(Info)) {
+	case symbol_CONSTANT:
+	  ActPos += fputs(" Con", stdout); break;
+	case symbol_FUNCTION:
+	  ActPos += fputs(" Fun", stdout); break;
+	case symbol_PREDICATE:
+	  ActPos += fputs(" Pre", stdout); break;
+	case symbol_JUNCTOR:
+	  ActPos += fputs(" Jun", stdout); break;
+	}
+	misc_PrintChar((ArityPos  - ActPos), ' '); putchar('|');
+	ActPos = ArityPos + 1 + printf(" %3d", Entry->arity);
+	misc_PrintChar((StatPos   - ActPos), ' '); putchar('|');
+	ActPos = StatPos + 1;
+	if (symbol_Type(Info) == symbol_FUNCTION) {
+	  switch (symbol_Stat(Info)) {
+	  case symbol_STATLEX:
+	    ActPos += fputs(" Lex", stdout); break;
+	  case symbol_STATMUL:
+	    ActPos += fputs(" Mul", stdout); break;
+	  }
+	}
+	misc_PrintChar((PropPos   - ActPos), ' '); putchar('|');
+	ActPos = PropPos + 1 + printf(" %u", Entry->props);
+	misc_PrintChar((StringPos - ActPos), ' '); putchar('|');
+	ActPos = StringPos + 1 +  printf(" %s", Entry->name);
+	misc_PrintChar((EndPos    - ActPos), ' '); putchar('|'); putchar('\n');
+      }
+    }
+    misc_PrintChar(symbol_TABLEBLANKS, ' '); putchar('+');
+    misc_PrintChar(symbol_TABLETYPE,   '-'); putchar('+');
+    misc_PrintChar(symbol_TABLEARITY,  '-'); putchar('+');
+    misc_PrintChar(symbol_TABLESTAT,   '-'); putchar('+');
+    misc_PrintChar(symbol_TABLEPROP,   '-'); putchar('|');
+    misc_PrintChar(symbol_TABLESTRING, '-'); putchar('+'); putchar('\n');
+  }
+}
+
diff --git a/test/spass/symbol.h b/test/spass/symbol.h
new file mode 100644
index 0000000000000000000000000000000000000000..a31f353af8b1f864e2e35be553368289f8c2acd1
--- /dev/null
+++ b/test/spass/symbol.h
@@ -0,0 +1,786 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                     SYMBOLS                            * */
+/* *                                                        * */
+/* *  $Module:   SYMBOL                                     * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 35442 $                                        * */
+/* $State$                                            * */
+/* $Date: 2007-03-28 17:24:40 -0700 (Wed, 28 Mar 2007) $                             * */
+/* $Author: jeffc $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#ifndef _SYMBOL_
+#define _SYMBOL_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "list.h"
+#include "stringsx.h"
+
+/**************************************************************/
+/* Data Structures and Constants                              */
+/**************************************************************/
+
+/* Critical values: the maximum length of a symbol string and the */
+/* maximum number of different variables (in one term, clause)    */
+/* CAUTION: symbol__MAXVARIABLES is the overall number of         */
+/*          variables + 1 to provide safe allocation of contexts  */
+/*          ... because the first var begins with 1 instead of 0. */
+
+#define symbol__SYMBOLMAXLEN   64
+
+#define symbol__NOOFSTANDARDVAR 2000
+#define symbol__NOOFINDEXVAR    1000
+
+#define symbol__MAXSTANDARDVAR  symbol__NOOFSTANDARDVAR
+#define symbol__MAXINDEXVAR     (symbol__NOOFSTANDARDVAR + symbol__NOOFINDEXVAR)
+
+#define symbol__NOOFVARIABLES (symbol__NOOFSTANDARDVAR + symbol__NOOFINDEXVAR)
+#define symbol__MAXVARIABLES  (symbol__NOOFVARIABLES + 1)
+
+/* Symbol Types, Symbols are represented as integers. In case of */
+/* constants, functions, predicates, junctors, the two least     */
+/* significant bits encode the type. Variables are just          */
+/* positive integers, all other symbols negative integers        */
+/* The third least significant bit encodes the status of         */
+/* function symbols (lexicographic or multiset)                  */
+
+extern const int symbol_MASK;
+extern const int symbol_TYPEMASK;
+extern const int symbol_STATMASK;
+extern const int symbol_TYPESTATMASK;
+
+extern const int symbol_ARBITRARYARITY;
+
+extern const int symbol_TYPEBITS;
+extern const int symbol_STATBITS;
+extern const int symbol_TYPESTATBITS;
+
+extern const int symbol_SIGTYPES;
+
+#define symbol_CONSTANT  0 
+#define symbol_FUNCTION  1
+#define symbol_PREDICATE 2
+#define symbol_JUNCTOR   3
+
+#define symbol_STATLEX   0 
+#define symbol_STATMUL   1
+
+/* For constants, functions, predicates, junctors, is a special */
+/* symbol table available, containing the arity, status and the */
+/* print name.                                                  */
+
+typedef int SYMBOL;
+typedef int *PRECEDENCE;
+
+typedef struct signature {
+  char   *name;         /* The name of the symbol as a string */
+  NAT    length;        /* The length of the name. Needed for efficient printing */
+  int    weight;        /* The weight of the symbol for ordering purposes */
+  int    arity;         /* The arity of the symbol */
+  NAT    props;         /* Special Properties of the symbol, e.g. AC, Skolem,... */
+  SYMBOL info;          /* 2 LSB denote Type and 3rd LSB denotes status */
+  LIST   generatedBy;
+} SIGNATURE_NODE, *SIGNATURE;
+
+typedef enum {SKOLEM=1,    CUMMUTATIVE=2, ASSOCIATIVE=4, ORDRIGHT=8, ORDMUL=16,
+	      DECLSORT=32, DOMPRED=64, ISDEF=128, FREELY=256, GENERATED=512
+} SPROPERTY;
+
+
+#define symbol__MAXSIGNATURE 4000
+
+extern SIGNATURE *symbol_SIGNATURE;
+
+extern SYMBOL symbol_STANDARDVARCOUNTER;
+extern SYMBOL symbol_INDEXVARCOUNTER;
+
+extern int symbol_ACTINDEX;
+extern int symbol_ACTSKOLEMFINDEX;
+extern int symbol_ACTSKOLEMCINDEX;
+extern int symbol_ACTSKOLEMPINDEX;
+extern int symbol_ACTSKOLEMAINDEX;
+
+/* For matching of signature symbols */
+extern SYMBOL symbol_CONTEXT[symbol__MAXSIGNATURE];
+
+
+/**************************************************************/
+/* Specials                                                   */
+/**************************************************************/
+
+NAT             symbol_MaxStringLength(void);
+
+void            symbol_ReinitGenericNameCounters(void);
+
+int             symbol_GetIncreasedOrderingCounter(void);
+
+void            symbol_Delete(SYMBOL);
+BOOL            symbol_IsSymbol(SYMBOL);
+void            symbol_Dump(PRECEDENCE);
+
+LIST            symbol_SortByPrecedence(LIST, PRECEDENCE);
+void            symbol_RearrangePrecedence(PRECEDENCE, LIST);
+
+void            symbol_LowerSignature(void);
+
+LIST            symbol_GetAllSymbols(void);
+LIST            symbol_GetAllPredicates(void);
+LIST            symbol_GetAllFunctions(void);
+
+void            symbol_SetCount(SYMBOL, unsigned long);
+unsigned long   symbol_GetCount(SYMBOL);
+/**************************************************************/
+/* Symbol Comparisons                                         */
+/**************************************************************/
+
+static __inline__ BOOL symbol_Equal(SYMBOL A, SYMBOL B)
+{
+  return A==B;
+}
+
+static __inline__ BOOL symbol_IsSignature(SYMBOL S)
+{
+  return S < 0;
+}
+
+static __inline__ void symbol_CheckNoVariable(SYMBOL S)
+{
+#ifdef CHECK
+  if (!symbol_IsSignature(S)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In symbol_CheckNoVariable: illegal input\n");
+    misc_FinishErrorReport();
+  }
+#endif
+}
+
+static __inline__ int symbol_Type(SYMBOL ActSymbol)
+{
+  symbol_CheckNoVariable(ActSymbol);
+  return (-ActSymbol) & symbol_TYPEMASK;
+}
+
+static __inline__ BOOL symbol_IsJunctor(SYMBOL S)
+{
+  return (symbol_IsSignature(S) && symbol_Type(S) == symbol_JUNCTOR);
+}
+
+static __inline__ BOOL symbol_IsFunction(SYMBOL S)
+{
+  return (symbol_IsSignature(S) &&
+	  (symbol_Type(S) == symbol_FUNCTION ||
+	   symbol_Type(S) == symbol_CONSTANT));
+}
+
+static __inline__ BOOL symbol_IsConstant(SYMBOL S)
+{
+  return (symbol_IsSignature(S) && symbol_Type(S) == symbol_CONSTANT);
+}
+
+static __inline__ BOOL symbol_IsPredicate(SYMBOL S)
+{
+  return (symbol_IsSignature(S) && symbol_Type(S) == symbol_PREDICATE);
+}
+
+static __inline__ BOOL symbol_IsVariable(SYMBOL S)
+{
+  return S > 0;
+}
+
+static __inline__ BOOL symbol_IsStandardVariable(SYMBOL S)
+{
+  return symbol_IsVariable(S) && (S <= symbol__MAXSTANDARDVAR);
+}
+
+static __inline__ BOOL symbol_IsIndexVariable(SYMBOL S)
+{
+  return (S > symbol__MAXSTANDARDVAR) && (S <= symbol__MAXINDEXVAR);
+}
+
+static __inline__ BOOL symbol_IsComplex(SYMBOL S)
+{
+  return (!symbol_IsVariable(S) && !symbol_IsConstant(S));
+}
+
+static __inline__ BOOL symbol_IsSuccessor(SYMBOL S, SYMBOL P)
+{
+  return S > P;
+}
+
+
+/**************************************************************/
+/* Symbol Manipulation                                        */
+/**************************************************************/
+
+static __inline__ int symbol_GetInitialStandardVarCounter(void)
+{
+  return 0;
+}
+
+static __inline__ int symbol_GetInitialIndexVarCounter(void)
+{
+  return symbol__MAXSTANDARDVAR;
+}
+
+static __inline__ int symbol_FirstIndexVariable(void)
+{
+  return symbol__MAXSTANDARDVAR + 1;
+}
+
+static __inline__ int symbol_LastIndexVariable(void)
+{
+  return symbol_INDEXVARCOUNTER;
+}
+
+/* Special predefined symbols            */
+
+#define symbol__NULL 0
+
+static __inline__ int symbol_MaxVars(void)
+{
+  return symbol__MAXVARIABLES;
+}
+
+static __inline__ int symbol_MaxConsts(void)
+{
+  return symbol__MAXSIGNATURE;
+}
+
+static __inline__ int symbol_MaxBaseSorts(void)
+{
+  return symbol__MAXSIGNATURE;
+}
+
+static __inline__ int symbol_TypeBits(void)
+{
+  return symbol_TYPEBITS;
+}
+
+static __inline__ int symbol_Null(void)
+{
+  return 0;
+}
+
+static __inline__ int symbol_ActIndex(void)
+{
+  return symbol_ACTINDEX;
+}
+
+static __inline__ void symbol_ResetSkolemIndex(void)
+{
+  symbol_ACTSKOLEMFINDEX = 0;
+  symbol_ACTSKOLEMCINDEX = 0;
+  symbol_ACTSKOLEMPINDEX = 0;
+  symbol_ACTSKOLEMAINDEX = 0;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  MEMORY MANAGEMENT                                     * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+static __inline__ void symbol_FreeSignature(SIGNATURE Sig)
+/***************************************************************
+  INPUT:   A signature datum.
+  RETURNS: void
+  EFFECTS: The datum is deleted and its memory freed.
+****************************************************************/
+{
+  memory_Free(Sig->name, symbol__SYMBOLMAXLEN);
+  list_Delete(Sig->generatedBy);
+  memory_Free(Sig, sizeof(SIGNATURE_NODE));
+}
+
+static __inline__ SIGNATURE symbol_GetSignature(void)
+{
+  return (SIGNATURE) memory_Malloc(sizeof(SIGNATURE_NODE));
+} 
+
+
+/**************************************************************/
+/* Symbol Creation                                            */
+/**************************************************************/
+
+static __inline__ SYMBOL symbol_CreateStandardVariable(void)
+/***************************************************************
+  INPUT:   None
+  RETURNS: A new symbol for a new standard variable numbered according to
+           symbol_STANDARDVARCOUNTER
+  SUMMARY: Creates a new standard variable symbol.
+  EFFECTS: None
+****************************************************************/
+{
+#ifdef CHECK
+  if (symbol_STANDARDVARCOUNTER >= symbol__MAXSTANDARDVAR) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In symbol_CreateStandardVariable: Number of standard variables exceeded.\n");
+    misc_FinishErrorReport();
+   }
+#endif
+
+  return (++symbol_STANDARDVARCOUNTER);
+}
+
+
+static __inline__ SYMBOL symbol_CreateIndexVariable(void)
+/***************************************************************
+  INPUT:   None
+  RETURNS: A new symbol for a new index variable numbered according to
+           symbol_INDEXVARCOUNTER
+  SUMMARY: Creates a new index variable symbol.
+  EFFECTS: None
+****************************************************************/
+{
+#ifdef CHECK
+  if (symbol_INDEXVARCOUNTER >= symbol__MAXINDEXVAR) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In symbol_CreateIndexVariable: Number of index variables exceeded.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  return (++symbol_INDEXVARCOUNTER);
+}
+
+
+static __inline__ SYMBOL symbol_NextIndexVariable(SYMBOL Variable)
+{
+#ifdef CHECK
+  if ((Variable != symbol_GetInitialIndexVarCounter() &&
+       !symbol_IsIndexVariable(Variable)) ||
+      Variable == symbol__MAXINDEXVAR) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In symbol_NextVariable: Illegal input.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  return (Variable + 1);
+}
+
+
+static __inline__ void symbol_SetStandardVarCounter(SYMBOL Variable)
+{
+#ifdef CHECK
+  if (Variable != symbol_GetInitialStandardVarCounter() &&
+      !symbol_IsStandardVariable(Variable)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In symbol_SetStandardVarCounter: Illegal input.\n");
+    misc_FinishErrorReport();
+  } 
+  else 
+    if (Variable >= symbol__MAXSTANDARDVAR) {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In symbol_SetStandardVarCounter: Number of standard variables exceeded.\n");
+      misc_FinishErrorReport();
+    }
+#endif
+
+  symbol_STANDARDVARCOUNTER = Variable;
+}
+
+static __inline__ SYMBOL symbol_FirstVariable(void)
+{
+  return 1;
+}
+
+static __inline__ BOOL symbol_GreaterVariable(SYMBOL Var1, SYMBOL Var2)
+{
+  return Var1 > Var2;
+}
+
+static __inline__ void symbol_ResetStandardVarCounter(void)
+{
+  symbol_STANDARDVARCOUNTER = symbol_GetInitialStandardVarCounter();
+}
+
+void   symbol_Init(BOOL);
+BOOL   symbol_SignatureExists(void);
+void   symbol_FreeAllSymbols(void);
+SYMBOL symbol_CreateFunction(const char*, int, int, PRECEDENCE);
+SYMBOL symbol_CreateSkolemFunction(int, PRECEDENCE);
+SYMBOL symbol_CreateSkolemPredicate(int, PRECEDENCE);
+SYMBOL symbol_CreatePredicate(const char*, int, int, PRECEDENCE);
+SYMBOL symbol_CreateJunctor(const char*, int, int, PRECEDENCE);
+
+/**************************************************************/
+/* Symbol Access                                              */
+/**************************************************************/
+
+SYMBOL symbol_Lookup(const char*);
+
+static __inline__ int symbol_VarIndex(SYMBOL ActSymbol)
+{
+  return ActSymbol;
+}
+
+static __inline__ int symbol_NormVar(SYMBOL ActSymbol)
+{
+  /* Normalization of variables s.t. the index of the variable
+     is normalized starting always with 1:
+     Standard variables are already normalized.
+     Index variables are decreased by the number of the
+     underlying standard variables. */
+  return (ActSymbol <= symbol__MAXSTANDARDVAR) ? ActSymbol : (ActSymbol - symbol__MAXSTANDARDVAR);
+}
+
+/* The name, index and arity macros are only defined for signature   */
+/* elements not for variables. The type of the symbol is not checked */
+/* by the macros.                                                    */
+
+static __inline__ int symbol_Index(SYMBOL ActSymbol)
+{
+  symbol_CheckNoVariable(ActSymbol);
+  return (-ActSymbol) >> symbol_TYPESTATBITS;
+}
+
+static __inline__ void symbol_CheckIndexInRange(int Index)
+{
+#ifdef CHECK
+  if (Index < 0 || Index >= symbol__MAXSIGNATURE) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In symbol_CheckIndexInRange: Symbol index is out of range.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+}
+
+static __inline__ SYMBOL symbol_SignatureSymbol(int ActIndex, int Type, int Status)
+{
+  return -((ActIndex << symbol_TYPESTATBITS)
+	   | (Status << symbol_TYPEBITS)
+	   | Type);
+}
+
+static __inline__ SIGNATURE symbol_Signature(int Index)
+  /* Returns the signature of the symbol with <Index> or NULL */
+  /* if the symbol was deleted */
+{
+  symbol_CheckIndexInRange(Index);
+  return symbol_SIGNATURE[Index];
+}
+
+static __inline__ void symbol_SetSignature(int ActIndex, SIGNATURE Sig)
+{
+  symbol_CheckIndexInRange(ActIndex);
+  symbol_SIGNATURE[ActIndex] = Sig;
+}
+
+static __inline__ SYMBOL symbol_GetSigSymbol(int Index)
+{
+  return symbol_Signature(Index)->info;
+}
+
+static __inline__ int symbol_Stat(SYMBOL ActSymbol)
+{
+  symbol_CheckNoVariable(ActSymbol);
+  return ((-ActSymbol) & symbol_STATMASK) >> symbol_TYPEBITS;
+}
+
+static __inline__ SYMBOL symbol_ChangeType(SYMBOL S, int Type)
+/**************************************************************
+  INPUT:   A symbol and a new type for that symbols.
+  RETURNS: A new symbol that is the old symbol with type changed to <Type>,
+           therefore the return value is different from <S>.
+  EFFECT:  Uses the signature memory of the input symbol.
+  CAUTION: Usage only allowed by the parsing modules!!!
+***************************************************************/
+{
+  SIGNATURE Sig;
+  symbol_CheckNoVariable(S);
+  Sig = symbol_Signature(symbol_Index(S));
+  S   = symbol_SignatureSymbol(symbol_Index(S), Type, symbol_Stat(S));
+  Sig->info = S;
+  return S;
+}
+
+static __inline__ int symbol_Arity(SYMBOL ActSymbol)
+{
+  return symbol_Signature(symbol_Index(ActSymbol))->arity;
+}
+
+static __inline__ NAT symbol_PositiveArity(SYMBOL ActSymbol)
+{
+  int arity = symbol_Arity(ActSymbol);
+  if (arity < 0)
+    return NAT_MAX;
+  else
+    return arity;
+}
+
+static __inline__ void symbol_SetArity(SYMBOL ActSymbol, int Arity)
+{
+  symbol_Signature(symbol_Index(ActSymbol))->arity = Arity;
+}
+  
+static __inline__ int symbol_ArbitraryArity(void)
+{
+  return -1;
+}
+
+static __inline__ char* symbol_Name(SYMBOL ActSymbol)
+{
+  return symbol_Signature(symbol_Index(ActSymbol))->name;
+}
+
+static __inline__ NAT symbol_NameLength(SYMBOL ActSymbol)
+{
+  return symbol_Signature(symbol_Index(ActSymbol))->length;
+}
+
+static __inline__ int symbol_Info(SYMBOL ActSymbol)
+{
+  return symbol_Signature(symbol_Index(ActSymbol))->info;
+}
+
+static __inline__ int symbol_Weight(SYMBOL ActSymbol)
+{
+  return symbol_Signature(symbol_Index(ActSymbol))->weight;
+}
+
+static __inline__ int symbol_Ordering(PRECEDENCE P, SYMBOL ActSymbol)
+{
+  int Index;
+  
+  Index = symbol_Index(ActSymbol);
+#ifdef CHECK
+  symbol_CheckIndexInRange(Index);
+  if (P[Index] < 0) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In symbol_Ordering: Ordering of symbol %s is invalid\n",
+		     symbol_Name(ActSymbol));
+    misc_FinishErrorReport();
+  }
+#endif
+  return P[Index];
+}
+
+static __inline__ void symbol_SetWeight(SYMBOL ActSymbol, int Weight)
+{
+  symbol_Signature(symbol_Index(ActSymbol))->weight = Weight;
+}
+
+static __inline__ void symbol_SetName(SYMBOL ActSymbol, char* Name)
+{
+  symbol_Signature(symbol_Index(ActSymbol))->name = Name;
+}
+
+static __inline__ LIST symbol_GeneratedBy(SYMBOL S)
+{
+  return symbol_Signature(symbol_Index(S))->generatedBy;
+}
+
+static __inline__ BOOL symbol_IsGeneratedBy(SYMBOL S1, SYMBOL S2)
+{
+  return list_PointerMember(symbol_GeneratedBy(S1), (POINTER)S2);
+}
+
+static __inline__ void symbol_SetGeneratedBy(SYMBOL S, LIST SymbolList)
+{
+  symbol_Signature(symbol_Index(S))->generatedBy = SymbolList;
+}
+
+static __inline__ void symbol_SetOrdering(PRECEDENCE P, SYMBOL ActSymbol,
+					  int Ordering)
+{
+  int Index;
+
+  Index = symbol_Index(ActSymbol);
+  symbol_CheckIndexInRange(Index);
+  P[Index] = Ordering;
+}
+
+static __inline__ void symbol_SetIncreasedOrdering(PRECEDENCE P, SYMBOL S)
+{
+  symbol_SetOrdering(P, S, symbol_GetIncreasedOrderingCounter());
+}
+
+
+static __inline__ BOOL symbol_PrecedenceGreater(PRECEDENCE P, SYMBOL S1, SYMBOL S2)
+{
+  return symbol_Ordering(P, S1) < symbol_Ordering(P, S2);
+}
+
+static __inline__ BOOL symbol_HasProperty(SYMBOL ActSymbol, SPROPERTY Property)
+{
+  return (symbol_Signature(symbol_Index(ActSymbol))->props & Property);
+}
+
+static __inline__ void symbol_AddProperty(SYMBOL ActSymbol, SPROPERTY Property)
+{
+  SIGNATURE S = symbol_Signature(symbol_Index(ActSymbol));
+  S->props    = S->props | Property;
+}
+
+static __inline__ void symbol_RemoveProperty(SYMBOL ActSymbol, SPROPERTY Property)
+{
+  SIGNATURE S = symbol_Signature(symbol_Index(ActSymbol));
+  if (S->props & Property)
+    S->props = S->props - Property;
+}
+
+static __inline__ BOOL symbol_IsBaseSort(SYMBOL Symbol)
+{
+  return (symbol_Arity(Symbol) == 1);
+}
+
+static __inline__ void symbol_ClearPrecedence(PRECEDENCE P)
+{
+  int i;
+  const int clear = -42; /* Some negative number */
+
+  for (i = 0; i < symbol__MAXSIGNATURE; i++)
+    P[i] = clear;        
+}
+
+static __inline__ PRECEDENCE symbol_CreatePrecedence(void)
+{
+  PRECEDENCE P;
+
+  P = memory_Malloc(sizeof(int[symbol__MAXSIGNATURE]));
+  symbol_ClearPrecedence(P);
+  return P;
+}
+
+static __inline__ void symbol_DeletePrecedence(PRECEDENCE P)
+{
+  memory_Free(P, sizeof(int[symbol__MAXSIGNATURE]));
+}
+
+static __inline__ void symbol_TransferPrecedence(PRECEDENCE Source,
+						 PRECEDENCE Target)
+  /* Copy settings from one precedence object to another */
+{
+  int i;
+
+  for (i = 0; i < symbol__MAXSIGNATURE; i++)
+    Target[i] = Source[i];
+}
+
+static __inline__ LIST symbol_DeleteSymbolFromList(LIST Symbols, SYMBOL S)
+  /* Deletes all occurrences of <S> from the list */
+{
+  return list_DeleteElement(Symbols, (POINTER) S, 
+			    (BOOL (*)(POINTER, POINTER)) symbol_Equal);
+}
+
+static __inline__ void symbol_DeleteSymbolList(LIST Symbols)
+  /* The list AND the symbols within are deleted */
+{
+  list_DeleteWithElement(Symbols, (void (*)(POINTER))symbol_Delete);
+}
+
+/**************************************************************/
+/* Symbol CONTEXT                                             */
+/**************************************************************/
+
+static __inline__ BOOL symbol_ContextIsClean(void)
+{
+  int i;
+  for (i = 0; i < symbol__MAXSIGNATURE; i++)
+    if (symbol_CONTEXT[i] != (SYMBOL)0)
+      return FALSE;
+  return TRUE;
+}
+
+static __inline__ void symbol_ContextClean(void)
+{
+  int i;
+  for (i = 0; i < symbol__MAXSIGNATURE; i++)
+    symbol_CONTEXT[i] = (SYMBOL)0;
+}
+
+static __inline__ BOOL symbol_ContextIsMapped(SYMBOL Symbol)
+{
+  int i;
+  for (i = 0; i < symbol__MAXSIGNATURE; i++)
+    if (symbol_Equal(symbol_CONTEXT[i],Symbol))
+      return TRUE;
+  return FALSE;
+}
+
+static __inline__ SYMBOL symbol_ContextGetValue(SYMBOL Symbol)
+{
+  int Index;
+
+  Index = symbol_Index(Symbol);
+  symbol_CheckIndexInRange(Index);
+  return symbol_CONTEXT[Index];
+}
+
+static __inline__ void symbol_ContextSetValue(SYMBOL Symbol, SYMBOL Value)
+{
+  int Index;
+
+  Index = symbol_Index(Symbol);
+  symbol_CheckIndexInRange(Index);
+  symbol_CONTEXT[Index] = Value;
+}
+
+static __inline__ void symbol_ContextClearValue(SYMBOL Symbol)
+{
+  symbol_ContextSetValue(Symbol, (SYMBOL)0);
+}
+
+static __inline__ BOOL symbol_ContextIsBound(SYMBOL Symbol)
+{
+  return (symbol_ContextGetValue(Symbol) != (SYMBOL)0);
+}
+
+/**************************************************************/
+/* Symbol Output                                              */
+/**************************************************************/
+
+void   symbol_Print(SYMBOL);
+void   symbol_PrintPrecedence(PRECEDENCE);
+void   symbol_FPrintPrecedence(FILE*, PRECEDENCE);
+void   symbol_FPrint(FILE*, SYMBOL);
+void   symbol_FPrintOtter(FILE*, SYMBOL);
+void   symbol_PrintLn(SYMBOL);
+void   symbol_PrintAll(void);
+
+#endif
diff --git a/test/spass/table.c b/test/spass/table.c
new file mode 100644
index 0000000000000000000000000000000000000000..639dbfd6f7a9a0060c1d44e1e4c6bfa7c4ecaded
--- /dev/null
+++ b/test/spass/table.c
@@ -0,0 +1,553 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *             SIGNATURE TABLE                            * */
+/* *                                                        * */
+/* *  $Module:   TABLE                                      * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1999, 2000, 2001 MPI fuer Informatik    * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                         * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "table.h"
+
+
+/**************************************************************/
+/* Inline functions                                           */
+/**************************************************************/
+
+static __inline__ int table_Index(SYMBOL symbol)
+{
+  if (symbol_IsVariable(symbol))
+    return -(int) symbol;
+  else
+    return symbol_Index(symbol);
+}
+
+
+static __inline__ TERM table_GetTerm(TERMARRAY ta)
+{
+  return ta->term;
+}
+
+
+static __inline__ TERMARRAY table_SetTerm(TERMARRAY ta, TERM term)
+{
+  ta->term = term;
+  return ta;
+}
+
+
+static __inline__ int table_GetStamp(TERMARRAY ta)
+{
+  return ta->stamp;
+}
+
+
+static __inline__ TERMARRAY table_SetStamp(TERMARRAY ta, int stamp)
+{
+  ta->stamp = stamp;
+  return ta;
+}
+
+
+static __inline__ TERMARRAY table_GetChild(TERMARRAY ta)
+{
+  return ta->child;
+}
+
+
+static __inline__ TERMARRAY table_SetChild(TERMARRAY ta, TERMARRAY child)
+{
+  ta->child = child;
+  return ta;
+}
+
+
+static __inline__ TERMARRAY table_GetTermarray(TABLE table)
+{
+  return table->ta;
+}
+
+
+static __inline__ TABLE table_SetTermarray(TABLE table, TERMARRAY ta)
+{
+  table->ta = ta;
+  return table;
+}
+
+
+static __inline__ TERMARRAY *table_GetPoss(TABLE table)
+{
+  return table->pos;
+}
+
+
+static __inline__ TERMARRAY table_GetPos(TABLE table, int index)
+{
+  return table_GetPoss(table)[index];
+}
+
+
+static __inline__ TABLE table_SetPoss(TABLE table, TERMARRAY *ref)
+{
+  table->pos = ref;
+  return table;
+}
+
+
+static __inline__ TABLE table_SetPos(TABLE table, int index, TERMARRAY ta)
+{
+  table_GetPoss(table)[index] = ta;
+  return table;
+}
+
+
+static __inline__ int *table_GetPosstamps(TABLE table)
+{
+  return table->posstamp;
+}
+
+
+static __inline__ int table_GetPosstamp(TABLE table, int index)
+{
+  return table_GetPosstamps(table)[index];
+}
+
+
+static __inline__ TABLE table_SetPosstamps(TABLE table, int *ref)
+{
+  table->posstamp = ref;
+  return table;
+}
+
+
+static __inline__ TABLE table_SetPosstamp(TABLE table, int index, int stamp)
+{
+  table_GetPosstamps(table)[index] = stamp;
+  return table;
+}
+
+
+static __inline__ int table_GetStampcounter(TABLE table)
+{
+  return table->stampcounter;
+}
+
+
+static __inline__ TABLE table_SetStampcounter(TABLE table, int stampcounter)
+{
+  table->stampcounter = stampcounter;
+  return table;
+}
+
+
+static __inline__ int table_GetOpbound(TABLE table)
+{
+  return table->opbound;
+}
+
+
+static __inline__ TABLE table_SetOpbound(TABLE table, int opbound)
+{
+  table->opbound = opbound;
+  return table;
+}
+
+
+static __inline__ int table_GetVarbound(TABLE table)
+{
+  return table->varbound;
+}
+
+
+static __inline__ TABLE table_SetVarbound(TABLE table, int varbound)
+{
+  table->varbound = varbound;
+  return table;
+}
+
+
+static __inline__ int table_GetTermbound(TABLE table)
+{
+  return table->termbound;
+}
+
+
+static __inline__ TABLE table_SetTermbound(TABLE table, int termbound)
+{
+  table->termbound = termbound;
+  return table;
+}
+
+
+static __inline__ BOOL table_LegalPosIndex(TABLE table, int index)
+{
+  return 0 <= index && index <= table_GetTermbound(table);
+}
+
+
+static __inline__ BOOL table_Stamped(TABLE table, TERMARRAY ta)
+{
+  return table_GetStamp(ta) == table_GetStampcounter(table);
+}
+
+
+static __inline__ TERMARRAY table_DelayedInit(TABLE table, TERMARRAY ta)
+/***************************************************************
+  INPUT:   a table and a termarray
+  RETURNS: the (now stamped) termarray
+  EFFECT:  partially initializes table by setting the
+	   termarray's entry to the empty term
+***************************************************************/
+{
+  if (!table_Stamped(table, ta)) {
+    table_SetTerm(ta, term_Null());
+    table_SetStamp(ta, table_GetStampcounter(table));
+  }
+  return ta;
+}
+
+
+static __inline__ BOOL table_PosStamped(TABLE table, int index)
+{
+  return table_GetPosstamp(table, index) == table_GetStampcounter(table);
+}
+
+
+static __inline__ int table_DelayedPosInit(TABLE table, int index)
+/***************************************************************
+  INPUT:   a table and a position index
+  RETURNS: the (now stamped) position index
+  EFFECT:  partially initializes table by setting the indexed
+	   position to the empty pointer, which means that the
+	   term with this index is not stored in table
+***************************************************************/
+{
+  if (!table_PosStamped(table, index)) {
+    table_SetPos(table, index, (TERMARRAY) NULL);
+    table_SetPosstamp(table, index, table_GetStampcounter(table));
+  }
+  return index;
+}
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+TABLE table_Null(void)
+{
+  return (TABLE) NULL;
+}
+
+
+TABLE table_Create(int opbound, int varbound, int termbound)
+/***************************************************************
+  INPUT:   bounds for the operator symbol, variable and term
+	   indices of the terms to be stored in the signature
+	   table (i. e. for every such term its top symbol index
+	   has to be in [1, opbound] and the term numbers of its
+	   arguments in [0, termbound] - or its variable index
+	   in [1, varbound] if it is a variable)
+  RETURNS: a new (and empty) signature table 
+***************************************************************/
+{
+  TABLE result;
+
+#ifdef CHECK
+  if (opbound < 0) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In table_Create: negative opbound.");
+    misc_FinishErrorReport();
+  }
+  if (varbound < 0) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In table_Create: negative varbound.");
+    misc_FinishErrorReport();
+  }
+  if (termbound < 0) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In table_Create: negative termbound.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  result = (TABLE) memory_Malloc(sizeof(struct table));
+  table_SetTermarray(result, (TERMARRAY) memory_Calloc (
+                                           opbound + varbound + 1,
+                                           sizeof(struct termarray)
+                                         ) + varbound);
+    /* move pointer to the middle of the array to allow negative indices */
+  table_SetPoss(
+    result,
+    (TERMARRAY*) memory_Malloc((termbound + 1) * sizeof(TERMARRAY))
+  );
+  table_SetPosstamps(result, (int*) memory_Calloc(termbound + 1, sizeof(int)));
+  table_SetOpbound(result, opbound);
+  table_SetVarbound(result, varbound);
+  table_SetTermbound(result, termbound);
+  table_SetStampcounter(result, 1);
+  return result;
+}
+
+
+static void table_FreeTermarray(TERMARRAY ta, int size)
+/***************************************************************
+  INPUT:  the termarray to free and its size
+  EFFECT: recursively frees the tree structure allocated for the
+	  signature array
+***************************************************************/
+{
+  int i;
+
+  if (ta) {
+    for (i = 0; i < size; i++)
+      table_FreeTermarray(table_GetChild(ta + i), size);
+    memory_Free(ta, size * sizeof(struct termarray));
+  }
+}
+
+
+void table_Free(TABLE table)
+{
+  int i;
+
+  if (table != table_Null()) {
+    for (i = -table_GetVarbound(table); i <= table_GetOpbound(table); i++)
+      table_FreeTermarray(
+        table_GetChild(table_GetTermarray(table) + i),
+        table_GetTermbound(table) + 1
+      );
+    memory_Free(
+      table_GetTermarray(table) - table_GetVarbound(table),
+      (table_GetOpbound(table) + table_GetVarbound(table) + 1) * sizeof(struct
+	termarray)
+    );
+    memory_Free(
+      table_GetPoss(table),
+      (table_GetTermbound(table) + 1) * sizeof(TERMARRAY)
+    );
+    memory_Free(
+      table_GetPosstamps(table),
+      (table_GetTermbound(table) + 1) * sizeof(int)
+    );
+    memory_Free(table, sizeof(struct table));
+  }
+}
+
+
+TABLE table_Init(TABLE table, int opbound, int varbound, int termbound)
+/***************************************************************
+  INPUT:   the table to recycle and bounds for the operator
+	   symbol, variable and term indices of the terms to be
+	   stored in the signature table (i. e. for every such
+	   term its top symbol index has to be in [1, opbound]
+	   and the term numbers of its arguments in
+	   [0, termbound] - or its variable index in
+	   [1, varbound] if it is a variable)
+  RETURNS: a cleaned up signature table 
+  CAUTION: potentially frees the old table, therefore must be
+	   called inside of an assignment like:
+	     table = table_Init(table, ...)
+***************************************************************/
+{
+  int opmax, varmax, termmax, i;
+  TERMARRAY old;
+
+#ifdef CHECK
+  if (opbound < 0) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In table_Init: negative opbound.");
+    misc_FinishErrorReport();
+  }
+  if (varbound < 0) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In table_Init: negative varbound.");
+    misc_FinishErrorReport();
+  }
+  if (termbound < 0) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In table_Init: negative termbound.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  opmax   = table_GetOpbound(table) > opbound ? table_GetOpbound(table) :
+	      opbound;
+  varmax  = table_GetVarbound(table) > varbound ? table_GetVarbound(table) :
+	      varbound;
+  termmax = table_GetTermbound(table) > termbound ? table_GetTermbound(table) :
+	      termbound;
+  table_SetStampcounter(table, table_GetStampcounter(table) + 1);
+
+  /* in case of stamp overflow or too small termarray nodes get a new table: */
+  if (table_GetStampcounter(table)<=0 || termbound>table_GetTermbound(table)) {
+    table_Free(table);
+    return table_Create(opmax, varmax, termmax);
+  }
+
+  /* if only the top layer of the tree is too small get a larger top layer: */
+  else if (opbound+varbound > table_GetOpbound(table)+table_GetVarbound(table)){
+    old = table_GetTermarray(table);
+    table_SetTermarray(table, (TERMARRAY) memory_Calloc(
+					    opmax + varmax + 1,
+					    sizeof(struct termarray)
+					  ) + varmax);
+    for (i = -table_GetVarbound(table); i <= table_GetOpbound(table); i++)
+      table_SetChild(table_GetTermarray(table) + i, table_GetChild(old + i));
+    memory_Free(
+      old - table_GetVarbound(table),
+      (table_GetOpbound(table) + table_GetVarbound(table) + 1) * sizeof(struct
+	termarray)
+    );
+    table_SetOpbound(table, opmax);
+    table_SetVarbound(table, varmax);
+    return table;
+  }
+
+  else {
+
+    /* move pointer to termarray's new middle: */
+    table_SetTermarray(
+      table,
+      table_GetTermarray(table) + table_GetOpbound(table) - opbound
+    );
+
+    table_SetVarbound(
+      table,
+      table_GetOpbound(table) + table_GetVarbound(table) - opbound
+    );
+    table_SetOpbound(table, opbound);
+    return table;
+  }
+}
+
+
+TERM table_QueryAndEnter(TABLE table, PARTITION p, TERM term)
+/***************************************************************
+  RETURNS: a term with the same p-signature (sigtab_Index(top
+	   symbol), [arg 1] , ..., [arg n] ) as term - or the
+                           p              p
+	   empty term if no such term exists
+  EFFECT:  term enters table in the latter case
+***************************************************************/
+{
+  TERMARRAY ta;
+  LIST terms;
+
+#ifdef CHECK
+  if (part_Size(p) - 1 > table_GetTermbound(table)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In table_QueryAndEnter: partition not suitable.");
+    misc_FinishErrorReport();
+  }
+  if (table_Index(term_TopSymbol(term)) > table_GetOpbound(table)) {
+    misc_StartErrorReport();
+    misc_ErrorReport
+      ("\n In table_QueryAndEnter: term's operation symbol out of bounds.");
+    misc_FinishErrorReport();
+  }
+  if (table_Index(term_TopSymbol(term)) < -table_GetVarbound(table)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In table_QueryAndEnter: variable out of bounds.");
+    misc_FinishErrorReport();
+  }
+  if (!table_LegalPosIndex(table, term_Size(term))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In table_QueryAndEnter: term out of bounds.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  ta = table_GetTermarray(table) + table_Index(term_TopSymbol(term));
+  for (terms = term_ArgumentList(term); !list_Empty(terms); terms =
+      list_Cdr(terms)) {
+    if (!table_GetChild(ta))
+      table_SetChild(ta, (TERMARRAY) memory_Calloc (
+                                       table_GetTermbound(table) + 1,
+                                       sizeof(struct termarray)
+                                     ));
+    ta = table_GetChild(ta) + part_Find(p, term_Size(list_Car(terms)));
+  }
+  table_DelayedInit(table, ta);
+  if (table_GetTerm(ta))
+    return table_GetTerm(ta);
+  else {
+    table_SetTerm(ta, term);
+    table_SetPos(table, table_DelayedPosInit(table, term_Size(term)), ta);
+    return term_Null();
+  }
+}
+
+
+TABLE table_Delete(TABLE table, TERM term)
+/***************************************************************
+  EFFECT: if term has entered table before, it is deleted
+***************************************************************/
+{
+  int no;
+
+#ifdef CHECK
+  if (!table_LegalPosIndex(table, term_Size(term))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In table_Delete: illegal table access.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  no = term_Size(term);
+  table_DelayedPosInit(table, no);
+  if (table_GetPos(table, no)) {
+
+#ifdef CHECK
+    if (!table_Stamped(table, table_GetPos(table, no))) {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In table_Delete: table corrupted.");
+      misc_FinishErrorReport();
+    }
+#endif
+
+    table_SetTerm(table_GetPos(table, no), term_Null());
+    table_SetPos(table, no, (TERMARRAY) NULL);
+  }
+  return table;
+}
+
diff --git a/test/spass/table.h b/test/spass/table.h
new file mode 100644
index 0000000000000000000000000000000000000000..e0024a402cdba702bee28c2d831508ad37c61d94
--- /dev/null
+++ b/test/spass/table.h
@@ -0,0 +1,101 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *             SIGNATURE TABLE                            * */
+/* *                                                        * */
+/* *  $Module:   TABLE                                      * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1999, 2000, 2001 MPI fuer Informatik    * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                         * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* module manages signature tables i. e. tables of terms (including the empty */
+/* term NULL) where the lookup key is the tuple of top symbol index and       */
+/* arguments' equivalence classes with respect to a partition p, the          */
+/* _p-signature_ (sigtab_Index(top symbol), [arg 1] , ..., [arg n] )          */
+/*                                                 p              p           */
+
+#ifndef _TABLE_
+#define _TABLE_
+
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "term.h"
+#include "partition.h"
+
+
+/**************************************************************/
+/* Basic types                                                */
+/**************************************************************/
+
+typedef struct termarray {
+  TERM term;
+  int stamp;
+  struct termarray *child;
+} *TERMARRAY;
+
+typedef struct table {
+  TERMARRAY ta, *pos;
+  int *posstamp, stampcounter, opbound, varbound, termbound;
+}
+*TABLE;
+
+/* a signature table is an "array of terms allocated by need" (i. e. a tree   */
+/* where the nodes of the same layer represent array entries with the same    */
+/* dimension), an array of positions in this "array", stamps for the          */
+/* positions, the stamp counter and bounds for the operator symbol, variable   */
+/* and term indices of the terms to be stored in the signature table (i. e.   */
+/* for every such term its top symbol index has to be in [1, opbound] and the */
+/* term numbers of its arguments in [0, termbound] - or its variable index in */
+/* [1, varbound] if it is a variable)                                         */
+
+
+/**************************************************************/
+/* Prototypes                                                 */
+/**************************************************************/
+
+TABLE table_Null(void);
+TABLE table_Create(int, int, int);
+void  table_Free(TABLE);
+TABLE table_Init(TABLE, int, int, int);
+TERM  table_QueryAndEnter(TABLE, PARTITION, TERM);
+TABLE table_Delete(TABLE, TERM);
+
+
+#endif
+
diff --git a/test/spass/tableau.c b/test/spass/tableau.c
new file mode 100644
index 0000000000000000000000000000000000000000..5b1ab8aa77d17c81433db38aa2b9c06c41a50440
--- /dev/null
+++ b/test/spass/tableau.c
@@ -0,0 +1,880 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                  TABLEAU PROOF TREES                   * */
+/* *                                                        * */
+/* *  Copyright (C) 1998, 1999, 2000, 2001                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+
+/* $RCSfile$ */
+
+#include "tableau.h" 
+
+/* for graph output */
+extern BOOL        pcheck_ClauseCg;
+extern GRAPHFORMAT pcheck_GraphFormat;
+
+TABPATH tab_PathCreate(int MaxLevel, TABLEAU Tab)
+/**************************************************************
+  INPUT:   A tableau, its maximum expected depth
+  RETURNS: A path consisting of the root  node of the tableau
+           which can have a max length of <MaxLevel>
+***************************************************************/
+{
+  TABPATH TabPath;
+
+  TabPath            = (TABPATH)memory_Malloc(sizeof(TABPATH_NODE));
+  TabPath->Path      = (TABLEAU*)memory_Malloc(sizeof(TABLEAU)*(MaxLevel+1));
+  TabPath->Path[0]   = Tab;
+  TabPath->MaxLength = MaxLevel;
+  TabPath->Length    = 0;
+  
+  return TabPath;
+}
+
+void tab_PathDelete(TABPATH TabPath)
+/**************************************************************
+  INPUT:   A tableau path.
+  RETURNS: Nothing.
+  EFFECTS: The path is deleted.
+***************************************************************/
+{
+  memory_Free(TabPath->Path, (TabPath->MaxLength+1)*sizeof(TABLEAU));
+  memory_Free(TabPath, sizeof(TABPATH_NODE));
+}
+
+
+BOOL tab_PathContainsClause(TABPATH Path, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A tableau path, a clause
+  RETURNS: TRUE iff the clause exists on its level (wrt. the
+           path) in the tableau
+***************************************************************/
+{
+  LIST Scan;
+
+  if (clause_SplitLevel(Clause) > tab_PathLength(Path))
+    return FALSE;
+
+  for (Scan = tab_Clauses(tab_PathNthNode(Path, clause_SplitLevel(Clause))); 
+       !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    if (list_Car(Scan) == Clause)
+      return TRUE;
+  }
+  return FALSE;
+}
+
+static BOOL tab_PathContainsClauseSoft(TABPATH Path, CLAUSE Clause)
+/**************************************************************
+  INPUT:   A tableau path, a clause
+  RETURNS: TRUE iff the clause is on one of the levels
+           in the tableau traversed by the path. Different
+	   from tab_PathContainsClauseSoft, since it does
+           not expect the clause on its split level.
+***************************************************************/
+{
+  LIST Scan;
+  int Level;
+
+  if (clause_SplitLevel(Clause) > tab_PathLength(Path))
+    return FALSE;
+  
+  for (Level = 0; Level <= tab_PathLength(Path); Level++) {
+    for (Scan = tab_Clauses(tab_PathNthNode(Path, Level));  
+	 !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+      if (list_Car(Scan) == Clause)
+	return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+/* unused */
+/*static*/ BOOL tab_PathContainsClauseRobust(TABPATH P, CLAUSE C)
+/**************************************************************
+  INPUT:   A tableau path, a clause
+  RETURNS: TRUE if clause can be find on the path (not
+           necessarily on its level)
+  EFFECTS: Prints a note if clause cannot be found on
+           its level. Intended for debugging.
+***************************************************************/
+{
+  if (tab_PathContainsClause(P,C)) 
+    return TRUE;
+
+  if (tab_PathContainsClauseSoft(P,C)) {
+    fputs("NOTE: Clause is found on path, but not indexed by level.\n", stderr);
+    clause_PParentsFPrint(stderr,C);
+    fflush(stderr);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+
+void tab_AddSplitAtCursor(TABPATH Path, BOOL LeftSide)
+/**************************************************************
+  INPUT:   A tableau path, a flag
+  RETURNS: Nothing.
+  EFFECTS: Extends the tableau containing the path <Path> to
+           the left if <LeftSide> is TRUE, to the right 
+	   otherwise
+***************************************************************/
+{
+  TABLEAU Tab, NewBranch;
+
+  Tab = tab_PathTop(Path);
+  NewBranch = tab_CreateNode();
+  if (LeftSide) {
+
+#ifdef CHECK
+    if (!tab_LeftBranchIsEmpty(Tab)) {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In tab_AddSplitAtCursor: Recreating existing");
+      misc_ErrorReport(" left branch in tableau.\n");
+      misc_FinishErrorReport();
+    }
+#endif
+
+    tab_SetLeftBranch(Tab,NewBranch);
+  } else {
+
+#ifdef CHECK    
+    if (!tab_RightBranchIsEmpty(Tab)) {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In tab_AddSplitAtCursor: Recreating existing");
+      misc_ErrorReport(" right branch in tableau.\n");
+      misc_FinishErrorReport();
+    }
+#endif
+    tab_SetRightBranch(Tab, NewBranch);
+  }
+  tab_PathPush(NewBranch, Path);
+}
+
+void tab_AddClauseOnItsLevel(CLAUSE C, TABPATH Path)
+/**************************************************************
+  INPUT:   A clause, a tableau path 
+  RETURNS: Nothing
+  EFFECTS: Adds the clause on its split level which
+           must belong to <Path>
+***************************************************************/
+{
+  int Level; 
+
+  Level = clause_SplitLevel(C);
+  if (Level > tab_PathLength(Path)) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\nError: Split level of some clause ");
+    misc_UserErrorReport("\nis higher than existing level."); 
+    misc_UserErrorReport("\nThis may be a bug in the proof file."); 
+    misc_FinishUserErrorReport();  
+  }
+  
+  tab_AddClause(C, tab_PathNthNode(Path, clause_SplitLevel(C)));
+}
+
+
+int tab_Depth(TABLEAU T)
+/**************************************************************
+  INPUT:   A tableau
+  RETURNS: The depth of the tableau
+***************************************************************/
+{
+  if (tab_IsEmpty(T))
+    return 0;
+  if (tab_IsLeaf(T))
+    return 0;
+  else 
+    return (misc_Max(tab_Depth(tab_RightBranch(T))+1, tab_Depth(tab_LeftBranch(T)))+1);
+}
+
+static BOOL tab_HasEmptyClause(TABLEAU T)
+/**************************************************************
+  INPUT:   A tableau                                                     
+  RETURNS: TRUE iff an empty clause is among the clauses
+           on this level
+***************************************************************/
+{
+  LIST Scan;
+  
+  for (Scan = tab_Clauses(T); !list_Empty(Scan); Scan = list_Cdr(Scan)) 
+    if (clause_IsEmptyClause(list_Car(Scan)))
+      return TRUE;
+
+  return FALSE;
+}
+
+
+BOOL tab_IsClosed(TABLEAU T)
+/**************************************************************
+  INPUT:   A Tableau   
+  RETURNS: TRUE iff the tableau is closed. (NOTE: FALSE
+           if the tableau is empty)
+***************************************************************/
+{
+  if (tab_IsEmpty(T))
+    return FALSE;
+
+  if (tab_HasEmptyClause(T))
+      return TRUE;
+  /* 
+   *  now tableau can only be closed
+   *  if there has been a split, and
+   *  both subtableaus are closed 
+   */
+  
+  if (tab_RightBranchIsEmpty(T) || tab_LeftBranchIsEmpty(T)) {
+    printf("\nopen node label: %d", T->Label);
+    fflush(stdout);
+
+    return FALSE;
+  }
+  return tab_IsClosed(tab_RightBranch(T)) && tab_IsClosed(tab_LeftBranch(T));
+}
+
+static LIST tab_DeleteFlat(TABLEAU T)
+/**************************************************************
+  INPUT:   A tableau
+  RETURNS: The list of its clauses on the first level of
+          the tableau
+  EFFECTS: Frees the root tableau node.
+***************************************************************/
+{
+  LIST Clauses;
+
+  Clauses = tab_Clauses(T);
+  memory_Free(T, sizeof(TABLEAU_NODE));
+  
+  return Clauses;
+}
+
+
+static void tab_DeleteGen(TABLEAU T, LIST* Clauses, BOOL DeleteClauses)
+/**************************************************************
+  INPUT:   A tableau, a list of clauses by reference, a flag 
+  RETURNS: Nothing
+  EFFECTS: Depending on <DeleteClauses>, all clauses in the
+           tableau are added to <Clauses> or just deleted.
+ 	   The memory for the tableau and its clause lists is
+	   freed.
+***************************************************************/
+{
+  if (tab_IsEmpty(T))
+    return;
+  
+  tab_DeleteGen(tab_RightBranch(T), Clauses, DeleteClauses);
+  tab_DeleteGen(tab_LeftBranch(T),  Clauses, DeleteClauses);
+
+  list_Delete(tab_RightSplitClauses(T));
+  if (DeleteClauses) 
+    list_Delete(tab_Clauses(T)); 
+  else
+    *Clauses = list_Nconc(tab_Clauses(T), *Clauses);
+  
+  tab_DeleteFlat(T);
+  
+}
+
+static void tab_DeleteCollectClauses(TABLEAU T, LIST* Clauses)
+/**************************************************************
+  INPUT:   A tableau, a list of clauses by reference
+  RETURNS: Nothing
+  EFFECTS: Frees the memory of the tableau, but collects
+           its clauses
+***************************************************************/
+{
+  tab_DeleteGen(T, Clauses, FALSE);
+}
+
+void tab_Delete(TABLEAU T)
+/**************************************************************
+  INPUT:   A tableau
+  RETURNS: Nothing
+  EFFECTS: Frees the memory of the tableau
+***************************************************************/
+{
+  LIST Redundant;
+  
+  Redundant = list_Nil();
+  tab_DeleteGen(T, &Redundant, TRUE);
+}
+
+static void tab_SetSplitLevelsRec(TABLEAU T, int Level)
+/**************************************************************
+  INPUT:   A tableau
+  RETURNS: Nothing                                                     
+  EFFECTS: The split levels of the clauses in the
+           tableau are set to the level of the
+	   tableau level they are contained in.
+***************************************************************/
+{
+  LIST Scan;
+
+  if (tab_IsEmpty(T))
+    return;
+  
+  for (Scan = tab_Clauses(T); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    clause_SetSplitLevel(list_Car(Scan), Level); 
+    if (Level >0) {
+      clause_ClearSplitField(list_Car(Scan));
+      clause_SetSplitFieldBit(list_Car(Scan), Level);
+    }
+    else 
+      clause_SetSplitField(list_Car(Scan), (SPLITFIELD)NULL,0);
+  }
+  
+  tab_SetSplitLevelsRec(tab_RightBranch(T), Level+1);
+  tab_SetSplitLevelsRec(tab_LeftBranch(T), Level+1);
+}
+
+void tab_SetSplitLevels(TABLEAU T)
+/**************************************************************
+  INPUT:   A tableau                                                     
+  RETURNS: Nothing                                                     
+  EFFECTS: The split levels of the clauses in the
+           tableau are set to the level of the
+	   tableau they belong to.
+***************************************************************/
+{
+  tab_SetSplitLevelsRec(T,0);
+}
+
+
+TABLEAU tab_PruneClosedBranches(TABLEAU T, LIST* Clauses) 
+/**************************************************************
+  INPUT:   A tableau, a list of clauses by reference.
+  RETURNS: The (destructively) reduced tableau: Descendants of
+           nodes that have an empty clause are deleted.
+  EFFECTS: The tableau is modified.
+***************************************************************/
+{
+  if (tab_IsEmpty(T))
+    return T;
+
+  /* if there is an empty clause on this level, delete subtrees */
+
+  if (tab_HasEmptyClause(T)) {
+
+    tab_DeleteCollectClauses(tab_RightBranch(T), Clauses); 
+    tab_DeleteCollectClauses(tab_LeftBranch(T), Clauses); 
+    tab_SetRightBranch(T, tab_EmptyTableau());
+    tab_SetLeftBranch(T, tab_EmptyTableau()); 
+    list_Delete(tab_RightSplitClauses(T));
+    tab_SetRightSplitClauses(T, list_Nil());
+    tab_SetSplitClause(T,clause_Null());
+    tab_SetLeftSplitClause(T, clause_Null());
+  }
+  /* else recursively prune subtrees */
+  else {
+    tab_SetRightBranch(T, tab_PruneClosedBranches(tab_RightBranch(T), Clauses));
+    tab_SetLeftBranch(T, tab_PruneClosedBranches(tab_LeftBranch(T), Clauses));
+  }
+  
+  return T;
+}
+
+
+TABLEAU tab_RemoveIncompleteSplits(TABLEAU T, LIST* Clauses)
+/**************************************************************
+  INPUT:   A Tableau, a list of clauses by reference
+  RETURNS: The reduced tableau: If a node has exactly one
+           successor (that is, the corresponding split was
+           not completed), delete the successor and move
+	   its subtrees to <T>.
+  EFFECTS: The successor node is deleted, and its clauses added
+           to <Clauses>
+***************************************************************/
+{
+  LIST    NewClauses;
+  TABLEAU Child;
+
+  if (tab_IsEmpty(T))
+    return T;
+
+  if (tab_IsLeaf(T))
+    return T;
+
+  if (!tab_IsEmpty(tab_RightBranch(T)) &&
+      !tab_IsEmpty(tab_LeftBranch(T))) {	   
+    tab_SetRightBranch(T, tab_RemoveIncompleteSplits(tab_RightBranch(T), Clauses));
+    tab_SetLeftBranch(T, tab_RemoveIncompleteSplits(tab_LeftBranch(T), Clauses));
+    return T;
+  }
+  if (tab_IsEmpty(tab_RightBranch(T))) 
+    Child = tab_LeftBranch(T);
+  else 
+    Child = tab_RightBranch(T);
+
+  Child = tab_RemoveIncompleteSplits(Child, Clauses);
+
+  tab_SetLeftBranch(T, tab_LeftBranch(Child));   
+  tab_SetRightBranch(T, tab_RightBranch(Child));
+
+  /* copy split data */
+
+  tab_SetSplitClause(T, tab_SplitClause(Child));
+  tab_SetLeftSplitClause(T, tab_LeftSplitClause(Child));
+  tab_SetRightSplitClauses(T, tab_RightSplitClauses(Child));
+
+  /* delete ancestors of deleted clauses and remember */
+
+  NewClauses = tab_DeleteFlat(Child);
+  (*Clauses) = list_Nconc(NewClauses, *Clauses);
+
+  return T;
+}
+
+
+void tab_CheckEmpties(TABLEAU T)
+/**************************************************************
+  INPUT:   A tableau 
+  RETURNS: Nothing.
+  EFFECTS: Prints warnings if non-leaf nodes contain
+           empty clauses (which should not be the case
+           after pruning any more), of if leaf nodes
+	   contain more than one empty clause
+***************************************************************/
+{
+  LIST Scan, Empties;
+  BOOL Printem;
+
+  if (tab_IsEmpty(T))
+    return;
+
+  /* get all empty clauses in this node */ 
+  Empties = list_Nil();
+  for (Scan = tab_Clauses(T); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    if (clause_IsEmptyClause(list_Car(Scan)))
+      Empties = list_Cons(list_Car(Scan), Empties);
+  }
+  Printem = FALSE;
+  if (!list_Empty(Empties) && !tab_IsLeaf(T)) {
+    puts("\nNOTE: non-leaf node contains empty clauses.");
+    Printem = TRUE;
+  }
+  
+  if (tab_IsLeaf(T) && list_Length(Empties) > 1) {
+    puts("\nNOTE: Leaf contains more than one empty clauses.");
+    Printem = TRUE;
+  }
+  if (Printem) {
+    puts("Clauses:");
+    clause_PParentsListPrint(tab_Clauses(T));
+  }
+  list_Delete(Empties);
+  tab_CheckEmpties(tab_LeftBranch(T));
+  tab_CheckEmpties(tab_RightBranch(T));
+}
+
+
+void tab_GetAllEmptyClauses(TABLEAU T, LIST* L)
+/**************************************************************
+  INPUT:   A tableau, a list by reference
+  RETURNS: All empty clauses in the tableau prepended to <L>.
+***************************************************************/
+{
+  if (tab_IsEmpty(T))
+    return;
+  
+  tab_GetAllEmptyClauses(tab_LeftBranch(T), L);
+  tab_GetAllEmptyClauses(tab_RightBranch(T), L);
+}
+
+
+void tab_GetEarliestEmptyClauses(TABLEAU T, LIST* L)
+/**************************************************************
+  INPUT  : A tableau, a list of clauses by reference
+  RETURNS: Nothing. 
+  EFFECTS: For each leaf node, adds empty clauses in
+           leaf nodes to <L>. If the leaf node contains only one
+	   empty clause, it is added to <L> anyway.
+           If the leaf node contains more than one empty clause,
+	   the earliest derived empty clause is added to <L>.
+***************************************************************/
+{
+  CLAUSE FirstEmpty;
+  LIST   Scan;
+
+  if (tab_IsEmpty(T))
+    return;
+
+  if (tab_IsLeaf(T)) {  
+    FirstEmpty = clause_Null();
+  
+    for (Scan = tab_Clauses(T); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+      if (clause_IsEmptyClause(list_Car(Scan))) {
+	if (FirstEmpty == clause_Null()) 
+	  FirstEmpty = list_Car(Scan);
+	else if (clause_Number(FirstEmpty) > clause_Number(list_Car(Scan)))
+	  FirstEmpty = list_Car(Scan);
+      }
+    }
+    
+    if (FirstEmpty != clause_Null())
+      (*L) = list_Cons(FirstEmpty, *L);
+  }
+  tab_GetEarliestEmptyClauses(tab_LeftBranch(T), L);
+  tab_GetEarliestEmptyClauses(tab_RightBranch(T), L);
+
+}
+
+void tab_ToClauseList(TABLEAU T, LIST* Proof)
+/**************************************************************
+  INPUT:   A tableau <T>, a list of clauses 
+  RETURNS: Nothing.
+  EFFECTS: All clauses in T are added to <Proof>
+***************************************************************/
+{
+  if (tab_IsEmpty(T))
+    return;
+  
+  (*Proof) = list_Nconc(list_Copy(tab_Clauses(T)), *Proof);
+
+  tab_ToClauseList(tab_LeftBranch(T),Proof);
+  tab_ToClauseList(tab_RightBranch(T),Proof);
+}
+
+
+static void tab_ToSeqProofOrdered(TABLEAU T, LIST* Proof)
+/**************************************************************
+  INPUT:   A tableau <T>, a list of clauses <Proof> representing a 
+           proof by reference
+  RETURNS: The sequential proof corresponding to the tableau.
+***************************************************************/
+{
+  LIST Scan;
+  BOOL RightSplitRead, LeftSplitRead;
+  
+  if (tab_IsEmpty(T))
+    return;
+
+  Scan = tab_Clauses(T); 
+  RightSplitRead = LeftSplitRead = FALSE;
+
+  while (!list_Empty(Scan)) {
+    /* insert left and right splits and descendants controlled by clause number */
+
+    if (!RightSplitRead && !tab_RightBranchIsEmpty(T) &&
+	clause_Number(list_Car(Scan)) <
+	clause_Number(list_Car(tab_RightSplitClauses(T)))) {
+      tab_ToSeqProofOrdered(tab_RightBranch(T), Proof);
+      RightSplitRead = TRUE;
+    }
+    if (!LeftSplitRead && !tab_LeftBranchIsEmpty(T) &&
+	clause_Number(list_Car(Scan)) < 
+	clause_Number(tab_LeftSplitClause(T))) {
+      tab_ToSeqProofOrdered(tab_LeftBranch(T), Proof);
+      LeftSplitRead  = TRUE;
+    }
+    (*Proof) = list_Cons(list_Car(Scan), *Proof); 
+    Scan  = list_Cdr(Scan);
+  }
+  /* if a split clause with descendants has not been inserted yet, 
+     it been generated after all other clauses */
+
+  if (!RightSplitRead)
+    tab_ToSeqProofOrdered(tab_RightBranch(T), Proof);
+  if (!LeftSplitRead)
+    tab_ToSeqProofOrdered(tab_LeftBranch(T), Proof);
+}
+
+
+/****************************************************************/
+/*  SPECIALS FOR GRAPHS                                         */
+/****************************************************************/
+
+static void tab_LabelNodesRec(TABLEAU T, int* Num)
+/**************************************************************
+  INPUT:   A Tableau, a number by reference
+  RETURNS: Nothing.
+  EFFECTS: Labels the tableau nodes dflr, starting with <Num>
+***************************************************************/
+{
+  if (tab_IsEmpty(T))
+    return;
+  T->Label = *Num;
+  (*Num)++;
+  tab_LabelNodesRec(tab_LeftBranch(T), Num);
+  tab_LabelNodesRec(tab_RightBranch(T), Num);
+}
+
+
+void tab_LabelNodes(TABLEAU T)
+/**************************************************************
+  INPUT:   A Tableau, a number by reference
+  RETURNS: Nothing.
+  EFFECTS: Labels the tableau nodes dflr, starting with 0
+***************************************************************/
+{
+  int Num;
+
+  Num = 0;
+  tab_LabelNodesRec(T, &Num);
+}
+
+
+static void tab_FPrintNodeLabel(FILE *File, TABLEAU T)
+/**************************************************************
+  INPUT:   A file handle, a tableau 
+  RETURNS: Nothing.
+  EFFECTS: Prints the root node information to <File>:
+           clauses, split information
+***************************************************************/
+{
+  LIST Scan;
+
+  /* start printing of node label string */
+  
+  fprintf(File, "\"label: %d\\n", T->Label);
+  
+  /* print left and right parts of split */
+  fputs("SplitClause : ", File); 
+  clause_PParentsFPrint(File, tab_SplitClause(T));
+  fputs("\\nLeft Clause : ", File);
+  clause_PParentsFPrint(File, tab_LeftSplitClause(T));
+  fputs("\\nRightClauses: ", File);
+  if (list_Empty(tab_RightSplitClauses(T)))
+    fputs("[]\\n", File);
+  else {
+    clause_PParentsFPrint(File, list_Car(tab_RightSplitClauses(T)));
+    fputs("\\n", File);
+    for (Scan = list_Cdr(tab_RightSplitClauses(T)); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+      fputs("              ", File);
+      clause_PParentsFPrint(File, list_Car(Scan));
+      fputs("\\n", File);
+    }
+  }
+  /* print clause at this level */
+  if (pcheck_ClauseCg) {
+    if (list_Empty(tab_Clauses(T)))
+      fputs("[]", File);
+    else {
+      for (Scan = tab_Clauses(T); !list_Empty(Scan); Scan = list_Cdr(Scan)){
+	clause_PParentsFPrint(File, list_Car(Scan)); 
+	fputs("\\n", File);
+      }
+    }
+  }
+  putc('"', File); /* close string */
+}
+
+
+static void tab_FPrintEdgeCgFormat(FILE* File, int Source, int Target, BOOL Left)
+/**************************************************************
+  INPUT:   A file handle, two node labels, a flag
+  RETURNS: Nothing.
+  EFFECTS: Prints the edge denoted by <Source> and <Target>
+           to <File>, with an edge label (0/1) according to <Left>.
+	   The edge label is added since xvcg cannot handle
+           ordered edges.
+***************************************************************/
+{
+  fputs("\nedge: {", File);
+  fprintf(File, "\nsourcename: \"%d\"", Source);
+  fprintf(File, "\ntargetname: \"%d\"\n", Target);
+  fputs("\nlabel: \"", File);
+  if (Left) 
+    putc('0', File);
+  else
+    putc('1', File);
+  fputs("\"  }\n", File);
+} 
+
+
+static void tab_FPrintEdgesCgFormat(FILE* File, TABLEAU T)
+/**************************************************************
+  INPUT:   A file handle, a tableau
+  RETURNS: Nothing.
+  EFFECTS: Prints edge information of <T> in xvcg graph format
+           to <File>.
+***************************************************************/
+{
+  if (tab_IsEmpty(T))
+    return;
+
+  if (!tab_LeftBranchIsEmpty(T))
+    tab_FPrintEdgeCgFormat(File, T->Label, tab_LeftBranch(T)->Label, TRUE);
+  if (!tab_RightBranchIsEmpty(T))
+    tab_FPrintEdgeCgFormat(File, T->Label, tab_RightBranch(T)->Label, FALSE);
+  
+  tab_FPrintEdgesCgFormat(File, tab_LeftBranch(T));
+  tab_FPrintEdgesCgFormat(File, tab_RightBranch(T));
+}
+
+
+static void tab_FPrintNodesCgFormat(FILE* File, TABLEAU T)
+/**************************************************************
+  INPUT:   A file handle, a tableau
+  RETURNS: Nothing
+  EFFECTS: Prints egde information of <T> in xvcg graph format
+           to <File>.                                            
+***************************************************************/
+{
+  if (tab_IsEmpty(T))
+    return;
+
+  fputs("\nnode: {\n\nlabel: ", File);
+  tab_FPrintNodeLabel(File, T);
+  putc('\n', File); /* end label section */
+  
+  fprintf(File, "title: \"%d\"\n", T->Label);
+  fputs("  }\n", File);
+  
+  /* recursion */
+  tab_FPrintNodesCgFormat(File, tab_LeftBranch(T));
+  tab_FPrintNodesCgFormat(File, tab_RightBranch(T));
+  
+} 
+
+static void tab_FPrintCgFormat(FILE* File, TABLEAU T)
+/**************************************************************
+  INPUT:   A file handle, a tableau
+  RETURNS: Nothing.
+  EFFECTS: Prints tableau as a graph in xvcg format to <File>
+***************************************************************/
+{
+  fputs("graph: \n{\ndisplay_edge_labels: yes\n", File);
+  
+  tab_FPrintNodesCgFormat(File, T);
+  tab_FPrintEdgesCgFormat(File, T); 
+  fputs("}\n", File);
+}
+
+/* unused */
+/*static*/ void tab_PrintCgFormat(TABLEAU T)
+/**************************************************************
+  INPUT:   A tableau. 
+  RETURNS: Nothing.                                                     
+  EFFECTS: Print tableau in xvcg format to stdout
+***************************************************************/
+{
+  tab_FPrintCgFormat(stdout, T);
+}
+
+
+/**************************************************************/
+/* procedures for printing graph in da Vinci format           */
+/**************************************************************/
+
+static void tab_FPrintDaVinciEdge(FILE* File, int L1, int L2)
+/**************************************************************
+  INPUT:   A file handle, two numbers 
+  RETURNS: Nothing 
+  EFFECTS: Print an edge in daVinci format
+***************************************************************/
+{
+  fprintf(File, "l(\"%d->%d\","   ,L1,L2);
+  fputs("e(\"\",[],\n", File);
+  /* print child node as reference */
+  fprintf(File, "r(\"%d\")))\n", L2);
+}
+
+
+static void tab_FPrintDaVinciFormatRec(FILE* File, TABLEAU T)
+/**************************************************************
+  INPUT:   A file handle, a tableau
+  RETURNS: Nothing
+  EFFECTS: Prints tableau to <File> in daVinci format
+***************************************************************/
+{
+  /* print node label */
+  fprintf(File, "l(\"%d\",", T->Label);
+  /* print node attributes */
+  fputs("n(\"\", [a(\"OBJECT\",", File); 
+  tab_FPrintNodeLabel(File, T);
+  fputs(")],\n", File);
+  
+  /* print egde list  */
+  putc('[', File);
+  if (!tab_LeftBranchIsEmpty(T)) 
+    tab_FPrintDaVinciEdge(File, T->Label, tab_LeftBranch(T)->Label); 
+
+  if (!tab_RightBranchIsEmpty(T)) {
+    if (!tab_LeftBranchIsEmpty(T))
+      putc(',', File);
+    tab_FPrintDaVinciEdge(File, T->Label, tab_RightBranch(T)->Label);
+  }
+  fputs("]))", File); /* this ends the node description */
+
+  if (!tab_LeftBranchIsEmpty(T)) {
+    putc(',', File);
+    tab_FPrintDaVinciFormatRec(File, tab_LeftBranch(T));
+  }
+  if (!tab_RightBranchIsEmpty(T)) {
+    putc(',', File);
+    tab_FPrintDaVinciFormatRec(File, tab_RightBranch(T));
+  }
+}
+
+
+static void tab_FPrintDaVinciFormat(FILE* File, TABLEAU T)
+/**************************************************************
+  INPUT:   A file handle <File>, a tableau
+  RETURNS: Nothing
+  EFFECTS: Print tableau in daVinci format to <File>
+***************************************************************/
+{
+  fputs("[\n", File);
+  tab_FPrintDaVinciFormatRec(File,T);
+  fputs("]\n", File);
+}
+
+
+void tab_WriteTableau(TABLEAU T, const char* Filename, GRAPHFORMAT Format)
+/**************************************************************
+  INPUT:   A tableau, a filename 
+  RETURNS: Nothing.
+***************************************************************/
+{
+  FILE*  File;
+  
+  if (Format != DAVINCI && Format != XVCG) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\nError: unknown output format for tableau.\n");
+    misc_FinishUserErrorReport();
+  }
+
+  File = misc_OpenFile(Filename, "w");
+
+  if (Format == DAVINCI)
+    tab_FPrintDaVinciFormat(File, T);
+  else 
+    if (Format == XVCG)
+      tab_FPrintCgFormat(File, T);
+
+  misc_CloseFile(File, Filename);
+}
diff --git a/test/spass/tableau.h b/test/spass/tableau.h
new file mode 100644
index 0000000000000000000000000000000000000000..f04a82655790ec71be0f585e383d7f39e5473fea
--- /dev/null
+++ b/test/spass/tableau.h
@@ -0,0 +1,292 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                     TABLEAUS                           * */
+/* *                                                        * */
+/* *  $Module:   TABLEAU                                    * */
+/* *                                                        * */
+/* *  Copyright (C) 1998, 1999, 2000, 2001                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _TABLEAU_
+#define _TABLEAU_
+
+
+#include "list.h"
+#include "clause.h"
+
+typedef struct TABLEAU_HELP {
+  LIST   Clauses;               /* all clauses generated on the split level */
+  CLAUSE SplitClause;           /* this levels split clause */
+
+  CLAUSE LeftSplitClause;       /* first clause generated by split  */
+  LIST   RightSplitClauses;     /* other clauses generated by split */
+
+  struct TABLEAU_HELP* LeftBranch;  /* branch corresponding to first split clause  */
+  struct TABLEAU_HELP* RightBranch; /* branch corresponding to other split clauses */
+
+  int  Label;
+} TABLEAU_NODE, *TABLEAU;
+
+
+typedef struct {
+  TABLEAU *Path;      /* An array of tableaux */
+  int     Length;
+  int     MaxLength;
+  
+} TABPATH_NODE, *TABPATH;
+
+/* tableau output formats */
+typedef enum { DAVINCI, XVCG } GRAPHFORMAT;
+
+
+TABPATH tab_PathCreate(int, TABLEAU);
+void    tab_PathDelete(TABPATH);
+BOOL    tab_PathContainsClause(TABPATH, CLAUSE);
+void    tab_AddClauseOnItsLevel(CLAUSE, TABPATH);
+void    tab_AddSplitAtCursor(TABPATH, BOOL);
+BOOL    tab_IsClosed(TABLEAU);
+TABLEAU tab_PruneClosedBranches(TABLEAU, LIST*);
+int     tab_Depth(TABLEAU);
+void    tab_SetSplitLevels(TABLEAU T);
+TABLEAU tab_RemoveIncompleteSplits(TABLEAU, LIST*);
+void    tab_PathDelete(TABPATH);
+void    tab_Delete(TABLEAU);
+void    tab_ToClauseList(TABLEAU, LIST*);
+void    tab_GetEarliestEmptyClauses(TABLEAU, LIST*);
+void    tab_WriteTableau(TABLEAU, const char*, GRAPHFORMAT);
+void    tab_CheckEmpties(TABLEAU);
+void    tab_GetAllEmptyClauses(TABLEAU, LIST*);
+void    tab_LabelNodes(TABLEAU);
+
+/* inline functions for tableau paths */
+
+static __inline__ int  tab_PathLength(TABPATH TabPath)
+{
+  return TabPath->Length;
+}
+
+static __inline__ TABLEAU tab_PathNthNode(TABPATH TabPath, int n)
+{
+#ifdef CHECK
+  if (n > TabPath->MaxLength) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In tab_PathNthNode:");
+    misc_ErrorReport(" Path length is %d,", tab_PathLength(TabPath));
+    misc_ErrorReport("\nnode %d was requested.\n", n);
+    misc_FinishErrorReport();
+  }
+#endif  
+
+  return TabPath->Path[n];
+}
+
+static __inline__ TABPATH tab_PathPush(TABLEAU Tab, TABPATH TabPath)
+{
+  TabPath->Length++;
+  TabPath->Path[TabPath->Length] = Tab;
+  
+#ifdef CHECK
+  if (TabPath->Length > TabPath->MaxLength) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In tab_PathPush: Maximum path length %d exceeded\n",
+		     TabPath->MaxLength);
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  return TabPath;
+}
+
+static __inline__ TABLEAU tab_EmptyTableau(void)
+{
+  return (TABLEAU)NULL;
+}
+
+static __inline__ TABPATH tab_PathPop(TABPATH TabPath)
+{
+#ifdef CHECK
+  if (TabPath->Length <= 0) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In tab_PathPop: Popping from empty path.\n");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  TabPath->Path[TabPath->Length--] = tab_EmptyTableau();
+  
+  return TabPath;
+}
+
+static __inline__ BOOL tab_PathEmpty(TABPATH P)
+{
+  return (tab_PathLength(P) == 0);
+}
+
+static __inline__ TABLEAU tab_CreateNode(void)
+{
+  TABLEAU Node;
+
+  Node = (TABLEAU)memory_Malloc(sizeof(TABLEAU_NODE));
+  Node->RightBranch = (TABLEAU)NULL;
+  Node->LeftBranch  = (TABLEAU)NULL;
+  Node->SplitClause = (CLAUSE)NULL;
+  Node->LeftSplitClause   = (CLAUSE)NULL;
+  Node->RightSplitClauses = list_Nil();
+
+  Node->Clauses     = list_Nil();
+ 
+#ifdef USE_LABEL
+  Node->Label       = 0;
+#endif
+  
+  return Node;
+}
+
+static __inline__ TABPATH tab_PathPrefix(int Level, TABPATH TabPath)
+{
+  TabPath->Length = Level;
+  return TabPath;
+}
+
+static __inline__ TABLEAU tab_PathTop(TABPATH Path)
+{
+  return tab_PathNthNode(Path, tab_PathLength(Path));
+}
+
+
+static __inline__ BOOL tab_IsEmpty(TABLEAU Tab)
+{
+ return (Tab == tab_EmptyTableau());
+}
+
+static __inline__ TABLEAU tab_RightBranch(TABLEAU Tab)
+{
+ return Tab->RightBranch;
+}
+
+static __inline__ TABLEAU tab_LeftBranch(TABLEAU Tab)
+{
+ return Tab->LeftBranch;
+}
+
+static __inline__ void tab_SetRightBranch(TABLEAU Tab, TABLEAU SubTab)
+{
+  Tab->RightBranch = SubTab;
+} 
+
+static __inline__ void tab_SetLeftBranch(TABLEAU Tab, TABLEAU SubTab)
+{
+  Tab->LeftBranch = SubTab;
+} 
+
+static __inline__ BOOL tab_RightBranchIsEmpty(TABLEAU Tab)
+{
+  return (Tab->RightBranch == tab_EmptyTableau());
+}
+
+static __inline__ BOOL tab_LeftBranchIsEmpty(TABLEAU Tab)
+{
+  return (Tab->LeftBranch == tab_EmptyTableau());
+}
+
+static __inline__ CLAUSE tab_SplitClause(TABLEAU Tab)
+{
+  return Tab->SplitClause;
+}
+
+static __inline__ void tab_SetSplitClause(TABLEAU Tab, CLAUSE C)
+{
+  Tab->SplitClause = C;
+}
+
+static __inline__ BOOL tab_HasSplit(TABLEAU T)
+{
+  return (tab_SplitClause(T) != clause_Null());
+}
+
+static __inline__ void tab_AddClause(CLAUSE C,TABLEAU T)
+{
+  T->Clauses = list_Cons(C,T->Clauses);
+}
+
+static __inline__ LIST tab_Clauses(TABLEAU T)
+{
+  return T->Clauses;
+}
+
+static __inline__ void tab_SetClauses(TABLEAU T, LIST Clauses)
+{
+  T->Clauses = Clauses;
+}
+
+static __inline__ CLAUSE tab_LeftSplitClause(TABLEAU T)
+{
+  return T->LeftSplitClause;
+}
+
+static __inline__ void tab_SetLeftSplitClause(TABLEAU T, CLAUSE C)
+{
+  T->LeftSplitClause = C;
+}
+
+
+static __inline__ LIST tab_RightSplitClauses(TABLEAU T)
+{
+  return T->RightSplitClauses;
+}
+
+
+static __inline__ void tab_SetRightSplitClauses(TABLEAU T, LIST L)
+{
+  T->RightSplitClauses = L;
+}
+
+static __inline__ void tab_AddRightSplitClause(TABLEAU T, CLAUSE C)
+{
+  T->RightSplitClauses = list_Cons(C, T->RightSplitClauses);
+}
+
+static __inline__ BOOL tab_IsLeaf(TABLEAU T)
+{
+  return (tab_RightBranchIsEmpty(T) && tab_LeftBranchIsEmpty(T));
+}
+
+#endif
diff --git a/test/spass/term.c b/test/spass/term.c
new file mode 100644
index 0000000000000000000000000000000000000000..2bc38e4d987bbc25b28a127339b571f6b14f93c8
--- /dev/null
+++ b/test/spass/term.c
@@ -0,0 +1,2551 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                       TERMS                            * */
+/* *                                                        * */
+/* *  $Module:   TERM                                       * */
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#include "term.h"
+
+/**************************************************************/
+/* Global variables                                           */
+/**************************************************************/
+
+NAT      term_MARK;
+POINTER  term_BIND[symbol__MAXVARIABLES][2];
+#ifdef CHECK
+BOOL term_BINDPHASE;
+#endif
+
+NAT  term_STAMP;
+BOOL term_STAMPBLOCKED;
+static BOOL term_STAMPOVERFLOW[term_MAXSTAMPUSERS];
+static NAT  term_STAMPUSERS;
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *							    * */
+/* *  TERM CREATION FUNCTIONS			            * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+void term_Init(void)
+/**********************************************************
+  INPUT:   None.
+  RETURNS: None.
+  CAUTION: The term module is initialized.
+***********************************************************/
+{
+  int i;
+
+  term_MARK = 1;
+
+  term_STAMP = 0;
+  term_STAMPBLOCKED = FALSE;
+  for (i = 0; i < term_MAXSTAMPUSERS; i++)
+    term_STAMPOVERFLOW[i] = FALSE;
+  term_STAMPUSERS = 0;
+#ifdef CHECK
+  term_BINDPHASE = FALSE;
+#endif
+}
+
+
+TERM term_Create(SYMBOL Symbol, LIST List)
+/**********************************************************
+  INPUT:   A symbol and a list of arguments.
+  RETURNS: A term consisting of the top symbol 'Symbol' and
+           the arguments stored in 'List'.
+  CAUTION: None.
+********************************************************/
+{
+  TERM Result;
+
+#ifdef CHECK
+  if (!symbol_IsSymbol(Symbol) || !term_IsTermList(List)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_Create: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Result         = (TERM)memory_Malloc(sizeof(TERM_NODE));
+  Result->symbol = Symbol;
+  Result->args   = List;
+  Result->super.termlist = list_Nil();
+  Result->stamp = 0;
+  Result->size = 0;
+  return Result;
+}
+
+TERM term_CreateAddFather(SYMBOL Symbol, LIST List)
+/**********************************************************
+  INPUT:   A symbol and a list of arguments.
+  RETURNS: A term consisting of the top symbol 'Symbol' and
+           the arguments stored in 'List'.
+           In contrast to term_Create the superterm members are set for the arguments.
+  CAUTION: None.
+********************************************************/
+{
+  TERM Result;
+  LIST l;
+  Result = term_Create(Symbol, List);
+  for (l=term_ArgumentList(Result); !list_Empty(l); l = list_Cdr(l))
+    term_RplacSuperterm((TERM) list_Car(l), Result);
+  return Result;
+}
+
+TERM term_CreateStandardVariable(void)
+/**********************************************************
+  RETURNS: Returns a term with a new variable as top symbol.
+***********************************************************/
+{
+  return term_Create(symbol_CreateStandardVariable(), list_Nil());
+}
+
+
+void term_Delete(TERM Term)
+/**********************************************************
+  INPUT:   A term.
+  SUMMARY: Deletes the term and frees the storage.
+  CAUTION: The arguments of Term are also deleted.
+********************************************************/
+{
+  if (term_IsComplex(Term)) {
+    LIST Scan;
+    for (Scan = term_ArgumentList(Term);
+	 list_Exist(Scan);
+	 Scan = list_Cdr(Scan))
+      term_Delete(list_Car(Scan));
+    list_Delete(term_ArgumentList(Term));
+  }
+  term_Free(Term);
+}
+
+
+void term_DeleteIterative(TERM Term)
+/**********************************************************
+  INPUT:   A term.
+  SUMMARY: Deletes the term and frees the storage.
+  CAUTION: The arguments of Term are also deleted.
+********************************************************/
+{
+  if (term_IsComplex(Term)) {
+    LIST Stack, Aux;
+    Stack = list_StackBottom();
+    do {
+      if (term_IsComplex(Term))
+	Stack = list_Push(term_ArgumentList(Term),Stack);
+      term_Free(Term);
+      while (!list_StackEmpty(Stack) && list_Empty(list_Top(Stack)))
+	Stack = list_Pop(Stack);
+      if (!list_StackEmpty(Stack)) {
+	Aux  = list_Top(Stack);
+	Term = (TERM)list_Car(Aux);
+	list_RplacTop(Stack, list_Cdr(Aux));
+	list_Free(Aux);
+      }
+    } while (!list_StackEmpty(Stack));
+  }
+  else
+    term_Free(Term);
+}
+
+/**************************************************************/
+/* ********************************************************** */
+/* *			                                    * */
+/* *  PRIMITIVE TERM FUNCTIONS                              * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+BOOL term_Equal(TERM Term1, TERM Term2)
+/*********************************************************
+  INPUT:   Two terms.
+  RETURNS: The boolean value TRUE if the terms are equal.
+  CAUTION: EQUAL FUNCTION- OR PREDICATE SYMBOLS SHARE THE
+           SAME ARITY. THIS IS NOT VALID FOR JUNCTORS!
+**********************************************************/
+{
+#ifdef CHECK
+  if (!term_IsTerm(Term1) || !term_IsTerm(Term2)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_Equal: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  /* if (term_IsIndexVariable(Term1))
+     puts("\nterm_Equal: Left index variable.");
+     else if (term_IsIndexVariable(Term2))
+     puts("\nterm_Equal: Right index variable.");
+
+     fflush(stdout); */
+
+  if (Term1 == Term2)   /* pointers are equal */
+    return TRUE;
+  else if (!term_EqualTopSymbols(Term1, Term2))
+    return FALSE;
+  else if (term_ArgumentList(Term1)) {
+    LIST Scan1, Scan2;
+    for (Scan1=term_ArgumentList(Term1), Scan2=term_ArgumentList(Term2);
+	list_Exist(Scan1) && list_Exist(Scan2);
+	Scan1=list_Cdr(Scan1), Scan2=list_Cdr(Scan2))
+      if (!term_Equal(list_Car(Scan1),list_Car(Scan2)))
+	return FALSE;
+    return (list_Empty(Scan1) ? list_Empty(Scan2) : FALSE);
+  } else
+    return TRUE;
+}
+
+
+BOOL term_EqualIterative(TERM Term1, TERM Term2)
+/*********************************************************
+  INPUT:   Two terms.
+  RETURNS: The boolean value TRUE if the terms are equal.
+  CAUTION: Notice that there may be symbols with arbitrary arity
+*******************************************************/
+{
+  LIST Stack1,Stack2;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term1) || !term_IsTerm(Term2)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_EqualIterative: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  Stack1 = Stack2 = list_StackBottom();
+  do {
+    if (term_EqualTopSymbols(Term1,Term2) &&
+	term_IsComplex(Term1) && term_IsComplex(Term2)) {
+      Stack1 = list_Push(term_ArgumentList(Term1),Stack1);
+      Stack2 = list_Push(term_ArgumentList(Term2),Stack2);
+    }
+    if (!term_EqualTopSymbols(Term1,Term2) ||
+	term_IsComplex(Term1) != term_IsComplex(Term2)) {
+      Stack1 = list_StackFree(Stack1);
+      Stack2 = list_StackFree(Stack2);
+      return FALSE;
+    }
+    while (!list_StackEmpty(Stack1) && list_Empty(list_Top(Stack1)))
+      if (!list_StackEmpty(Stack2) && list_Empty(list_Top(Stack2))) {
+	Stack1 = list_Pop(Stack1);
+	Stack2 = list_Pop(Stack2);
+      }
+      else {
+	Stack1 = list_StackFree(Stack1);
+	Stack2 = list_StackFree(Stack2);
+	return FALSE;
+      }
+    if (!list_StackEmpty(Stack1)) {
+      if (!list_Empty(list_Top(Stack2))) {
+	Term1 = (TERM)list_Car(list_Top(Stack1));
+	list_RplacTop(Stack1, list_Cdr(list_Top(Stack1)));
+	Term2 = (TERM)list_Car(list_Top(Stack2));
+	list_RplacTop(Stack2, list_Cdr(list_Top(Stack2)));
+      }
+      else {
+	Stack1 = list_StackFree(Stack1);
+	Stack2 = list_StackFree(Stack2);
+	return FALSE;
+      }
+    }
+  } while (!list_StackEmpty(Stack1));
+  return TRUE;
+}
+
+
+BOOL term_VariableEqual(TERM Variable1, TERM Variable2)
+/*********************************************************
+  INPUT:   Two Variables.
+  RETURNS: The boolean value TRUE, if the variables are
+           equal.
+**********************************************************/
+{
+  return term_EqualTopSymbols(Variable1, Variable2);
+}
+
+
+BOOL term_IsGround(TERM Term)
+/**********************************************************
+  INPUT:   A term.
+  RETURNS: A boolean value which is TRUE, if 'Term' is a
+           ground term, i.e. does not contain variables.
+********************************************************/
+{
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_IsGround: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  if (term_IsComplex(Term)) {
+    LIST Stack;
+    Stack = list_StackBottom();
+    do {
+      if (term_IsComplex(Term))
+	Stack = list_Push(term_ArgumentList(Term),Stack);
+      else
+	if (term_IsVariable(Term)) {
+	  Stack = list_StackFree(Stack);
+	  return FALSE;
+	}
+      while (!list_StackEmpty(Stack) && list_Empty(list_Top(Stack)))
+	Stack = list_Pop(Stack);
+      if (!list_StackEmpty(Stack)) {
+	Term = (TERM)list_Car(list_Top(Stack));
+	list_RplacTop(Stack, list_Cdr(list_Top(Stack)));
+      }
+    } while (!list_StackEmpty(Stack));
+    return TRUE;
+  } else
+    return !term_IsVariable(Term);
+}
+
+
+BOOL term_IsTerm(TERM Term)
+/*********************************************************
+  INPUT:   A term.
+  RETURNS: TRUE, if 'Term' is not NULL
+           and has a symbol as its top symbol.
+**********************************************************/
+{
+  return (Term != (TERM)NULL && symbol_IsSymbol(term_TopSymbol(Term)));
+}
+
+
+BOOL term_IsTermList(LIST TermList)
+/*********************************************************
+  INPUT:   A term.
+  RETURNS: TRUE iff <TermList> is a list of terms.
+*******************************************************/
+{
+  for ( ; !list_Empty(TermList); TermList=list_Cdr(TermList))
+    if (!(term_IsTerm((TERM)list_Car(TermList))))
+      return FALSE;
+
+  return TRUE;
+}
+
+
+BOOL term_AllArgsAreVar(TERM Term)
+/*********************************************************
+  INPUT:   A term.
+  RETURNS: The boolean value TRUE, if all arguments of the
+           term are variables.
+*******************************************************/
+{
+  LIST Scan;
+  for (Scan = term_ArgumentList(Term);
+       !list_Empty(Scan); Scan = list_Cdr(Scan))
+    if (!term_IsVariable(list_Car(Scan)))
+      return FALSE;
+  return TRUE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *			LOW LEVEL FUNCTIONS	            * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+TERM term_Copy(TERM Term)
+/**********************************************************
+  INPUT:   A term.
+  RETURNS: A copy of 'Term' where the stamp field is copied, too.
+  SUMMARY: Copies "Term" and returns a pointer to the copy.
+*********************************************************/
+{
+  TERM Result;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_Copy: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (term_IsComplex(Term)) {
+    LIST Scan, ArgumentList;
+    for (Scan = ArgumentList = list_Copy(term_ArgumentList(Term));
+	 list_Exist(Scan);
+	 Scan = list_Cdr(Scan))
+      list_Rplaca(Scan, term_Copy(list_Car(Scan)));
+    Result = term_Create(term_TopSymbol(Term), ArgumentList);
+  } else
+    Result = term_Create(term_TopSymbol(Term), list_Nil());
+
+  Result->stamp = Term->stamp;
+  Result->size  = Term->size;
+
+  return Result;
+}
+
+
+TERM term_CopyIterative(TERM Term)
+/**********************************************************
+  INPUT:   A term.
+  RETURNS: A copy of <Term>.
+  SUMMARY: Copies <Term> and returns a pointer to the copy.
+*********************************************************/
+{
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_CopyIterative: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (term_IsComplex(Term)) {
+    LIST TopStack, ArgumentStack, ActStack;
+    TopStack      = list_Push((POINTER)term_TopSymbol(Term),
+			      list_StackBottom());
+    ArgumentStack = list_Push(list_Copy(term_ArgumentList(Term)),
+			      list_StackBottom());
+    ActStack      = list_Push(list_Top(ArgumentStack),
+			      list_StackBottom());
+
+    while (!list_StackEmpty(TopStack)) {
+      if (list_Empty(list_Top(ActStack))) {
+	Term = term_Create((SYMBOL)list_Top(TopStack),
+			   (LIST)list_Top(ArgumentStack));
+	TopStack = list_Pop(TopStack);
+	ArgumentStack = list_Pop(ArgumentStack);
+	ActStack = list_Pop(ActStack);
+	if (!list_StackEmpty(TopStack)) {
+	  list_Rplaca(list_Top(ActStack), Term);
+	  list_RplacTop(ActStack, list_Cdr(list_Top(ActStack)));
+	}
+      }
+      else {
+	Term = (TERM)list_Car(list_Top(ActStack));
+	if (term_IsComplex(Term)) {
+	  TopStack      = list_Push((POINTER)term_TopSymbol(Term), TopStack);
+	  ArgumentStack = list_Push(list_Copy(term_ArgumentList(Term)),
+				    ArgumentStack);
+	  ActStack      = list_Push(list_Top(ArgumentStack), ActStack);
+	}
+	else {
+	  list_Rplaca(list_Top(ActStack),
+		      term_Create(term_TopSymbol(Term), list_Nil()));
+	  list_RplacTop(ActStack, list_Cdr(list_Top(ActStack)));
+	}
+      }
+    }
+    return Term;
+  }
+  else
+    return term_Create(term_TopSymbol(Term), list_Nil());
+}
+
+
+TERM term_CopyWithEmptyArgListNode(TERM Term, LIST ArgListNode,
+				   LIST* ListNodeCopyPt)
+/**********************************************************
+  INPUT:   A term and a pointer to an argument list node of
+           this term.
+  RETURNS: A copy of 'Term' with a NULL as list_Car(ListNodeCopy).
+  SUMMARY: Copies "Term" and returns a pointer to the copy.
+*********************************************************/
+{
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_CopyWithEmptyArgListNode: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (term_IsComplex(Term)) {
+    LIST Scan, ArgumentList, HelpScan;
+    TERM Result;
+
+    HelpScan = term_ArgumentList(Term);
+    ArgumentList = list_Copy(HelpScan);
+
+    for (Scan = ArgumentList;
+	 list_Exist(Scan);
+	 Scan = list_Cdr(Scan),HelpScan = list_Cdr(HelpScan))
+      if (HelpScan != ArgListNode)
+	list_Rplaca(Scan,
+		    term_CopyWithEmptyArgListNode(list_Car(Scan),
+						  ArgListNode,
+						  ListNodeCopyPt));
+      else{
+	list_Rplaca(Scan, (TERM)NULL);
+	*ListNodeCopyPt = Scan;
+      }
+
+    Result         = (TERM)memory_Malloc(sizeof(TERM_NODE));
+    Result->symbol = term_TopSymbol(Term);
+    Result->args   = ArgumentList;
+    Result->super.termlist = list_Nil();
+
+    return Result;
+
+  } else
+    return term_Create(term_TopSymbol(Term), list_Nil());
+}
+
+
+void term_PrintWithEmptyArgListNode(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: none.
+  SUMMARY: Prints any term to stdout, especially terms with empty
+           argument list nodes.
+  CAUTION: Uses the other term_Output functions.
+*************************************************************/
+{
+  if (Term == (TERM)NULL)
+    fputs("(NULL)", stdout);
+  
+  else if (term_IsComplex(Term)) {
+    putchar('(');
+    symbol_Print(term_TopSymbol(Term));
+    putchar(' ');
+    list_Apply((void (*)(POINTER)) term_PrintWithEmptyArgListNode,
+	       term_ArgumentList(Term));
+    putchar(')');
+    
+  } else if (term_IsVariable(Term)) {
+    
+    symbol_Print(term_TopSymbol(Term));
+    
+  } else {
+    
+    /* term_IsConstant(Term) */
+    putchar('(');
+    symbol_Print(term_TopSymbol(Term));
+    putchar(')');
+  }
+}
+
+
+BOOL term_ReplaceSubtermBy(TERM Atom, TERM TermS, TERM TermT)
+/**************************************************************
+  INPUT:   Three terms.
+  RETURNS: None.
+  EFFECT:  Replaces all occurrences of TermS in Atom by TermT.
+           Top level is NOT considered!
+*************************************************************/
+{
+  LIST ArgListNode;
+  BOOL Replaced;
+  int B_Stack;
+
+#ifdef CHECK
+  if (!term_IsTerm(Atom) || !term_IsTerm(TermS) ||
+      !term_IsTerm(TermT) || term_Equal(Atom, TermS)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_ReplaceSubtermBy: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  /*fputs("\nWe look for: ",stdout);term_Print(TermS);
+    fputs("\nin: ",stdout);term_Print(Atom);
+  */
+
+  Replaced = FALSE;
+  TermS    = term_Copy(TermS);
+
+  if (!term_Equal(Atom, TermS) && !list_Empty(term_ArgumentList(Atom))) {
+
+    B_Stack = stack_Bottom();
+    stack_Push(term_ArgumentList(Atom));
+    
+    while (!stack_Empty(B_Stack)) {
+      ArgListNode = stack_Top();
+      Atom        = (TERM)list_Car(ArgListNode);
+      stack_RplacTop(list_Cdr(ArgListNode));
+      
+      if (term_Equal(Atom, TermS)) {
+	Replaced = TRUE;
+	list_Rplaca(ArgListNode, term_Copy(TermT));
+	term_Delete(Atom);
+      }
+      else
+	if (term_IsComplex(Atom))
+	  stack_Push(term_ArgumentList(Atom));
+      
+      while (!stack_Empty(B_Stack) && list_Empty(stack_Top()))
+	stack_Pop();
+    }
+  }
+  term_Delete(TermS);
+  return Replaced;
+}
+
+
+void term_ReplaceVariable(TERM Term, SYMBOL Symbol, TERM Repl)
+/**************************************************************
+  INPUT:   A term, a variable symbol and a replacement term.
+  RETURNS: void
+  EFFECT:  All variables with <Symbol> in <Term> are replaced 
+           with copies of <Repl>
+  CAUTION: Destructive
+***************************************************************/
+{
+  LIST Scan;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term) || !term_IsTerm(Repl) || !symbol_IsVariable(Symbol)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_ReplaceVariable: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  if (symbol_Equal(term_TopSymbol(Term), Symbol)) {
+    term_RplacTop(Term,term_TopSymbol(Repl));
+    term_RplacArgumentList(Term,term_CopyTermList(term_ArgumentList(Repl)));
+  }
+  else
+    for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+      term_ReplaceVariable(list_Car(Scan),Symbol,Repl);
+}
+
+void term_ExchangeVariable(TERM Term, SYMBOL Old, SYMBOL New)
+/**************************************************************
+  INPUT:   A term, and two variable symbols.
+  RETURNS: void
+  EFFECT:  All variables <Old> in <Term> are replaced with <New>
+  CAUTION: Destructive
+***************************************************************/
+{
+  LIST Scan;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term) || !symbol_IsVariable(Old) || !symbol_IsVariable(New)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_ExchangeVariable: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (symbol_Equal(term_TopSymbol(Term), Old))
+    term_RplacTop(Term,New);
+  else
+    for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan))
+      term_ExchangeVariable(list_Car(Scan),Old,New);
+}
+
+
+BOOL term_SubstituteVariable(SYMBOL Symbol, TERM Repl, TERM* Term)
+/******************************************************
+   INPUT:   A Symbol which has to be found in the Term,
+            a term which is the replacement for the    
+            'Symbol', and a term in which the substitu-
+            tions take place.                          
+   RETURNS: A boolean value which is TRUE, if any sub- 
+            stitutions were made.                      
+   SUMMARY: term_Substitute works recursively and repl.
+            every occurence of 'Symbol' in 'Term' by   
+            'Repl'.                                    
+   CAUTION: FUNCTION IS DESTRUCTIVE ON 'Term'. REPLACE-
+            MENT IS COPIED EACH TIME A SUB. TAKES PLACE
+*******************************************************/
+{
+#ifdef CHECK
+  if (!term_IsTerm(*Term) || !term_IsTerm(Repl) || !symbol_IsSymbol(Symbol)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_SubstituteVariable: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (symbol_Equal(term_TopSymbol(*Term), Symbol)) {
+    
+    TERM New;
+    New             = term_Copy(Repl);
+    (*Term)->symbol = Repl->symbol;
+    (*Term)->args   = term_ArgumentList(New);
+    
+    /* Free Top-Node of New, as the symbol has been written */
+    /* into the node pointed to by `Term'. */
+    memory_Free(New, sizeof(TERM_NODE));
+    return TRUE;
+ 
+  } else {
+    
+    BOOL Result;
+    LIST List;
+    
+    Result	= FALSE;
+    for (List	= term_ArgumentList(*Term);
+	 list_Exist(List); List = list_Cdr(List))
+      if (term_SubstituteVariable(Symbol, Repl, (TERM*) &(List->car)))
+	Result  = TRUE;
+    return Result;
+  }
+}
+
+
+static int term_CompareByConstants(TERM Left, TERM Right)
+/**************************************************************
+  INPUT:   Two terms.
+  RETURNS:  1 if left term < right term
+            0 if left term = right term
+	   -1 if left term > right term
+  EFFECT:  The terms are compared by their multisets of 
+           constants. The frequency of elements in the
+	   multisets is a multiset itself. The frequencies
+	   are sorted and the resulting sorted multisets
+	   compared.
+***************************************************************/
+{
+  LIST lconsts, rconsts;
+  int result;
+
+  /* Get multiset of constants. */
+
+  lconsts = term_ListOfConstants(Left);
+  rconsts = term_ListOfConstants(Right);
+
+  result  = list_CompareMultisetsByElementDistribution(lconsts, rconsts); 
+
+  list_Delete(lconsts);
+  list_Delete(rconsts);
+
+  return result;
+}
+
+static int term_CompareByFunctions(TERM Left, TERM Right) 
+/**************************************************************
+  INPUT:   Two terms.
+  RETURNS:  1 if left term < right term
+            0 if left term = right term
+	   -1 if left term > right term
+  EFFECT:  The terms are compared by their multisets of 
+           functions. The frequency of elements in the
+	   multisets is a multiset itself. The frequencies
+	   are sorted and the resulting sorted multisets
+	   compared.
+***************************************************************/
+{
+  LIST lfuns, rfuns;
+  int result;
+
+  /* Get multiset of functions. */
+
+  lfuns = term_ListOfFunctions(Left);
+  rfuns = term_ListOfFunctions(Right);
+
+  result  = list_CompareMultisetsByElementDistribution(lfuns, rfuns); 
+
+  list_Delete(lfuns);
+  list_Delete(rfuns);
+
+  return result;
+}
+
+static int term_CompareByVariables(TERM Left, TERM Right) 
+/**************************************************************
+  INPUT:   Two terms.
+  RETURNS:  1 if left term < right term
+            0 if left term = right term
+	   -1 if left term > right term
+  EFFECT:  The terms are compared by their multisets of 
+           variables. The frequency of elements in the
+	   multisets is a multiset itself. The frequencies
+	   are sorted and the resulting sorted multisets
+	   compared.
+***************************************************************/
+{
+  LIST lvars, rvars;
+  int result;
+
+  /* Get multiset of variables. */
+
+  lvars = term_ListOfVariables(Left);
+  rvars = term_ListOfVariables(Right);
+
+  result  = list_CompareMultisetsByElementDistribution(lvars, rvars); 
+
+  list_Delete(lvars);
+  list_Delete(rvars);
+
+  return result;
+}
+
+LIST term_ListOfConstants(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: A list of constants.
+  EFFECT:  Creates a list of constants used in a term. If no
+           constants are used in a term, it returns an empty 
+	   list.
+***************************************************************/
+{
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_ListOfConstants: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (symbol_IsConstant(term_TopSymbol(Term)))
+    return list_List((POINTER) term_TopSymbol(Term));
+  else {
+    LIST result;
+    LIST scan;
+  
+    result = list_Nil();
+    for (scan = term_ArgumentList(Term); 
+	 !list_Empty(scan); 
+	 scan = list_Cdr(scan)) {
+      /* Append to the smaller list for efficiency. 
+	 A subterm's list of constants will usually 
+	 be smaller than the intermediate result.
+      */
+      result = list_Nconc(term_ListOfConstants((TERM) list_Car(scan)), result);
+    }
+
+    return result;
+  }
+}
+
+LIST term_ListOfFunctions(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: A list of functions.
+  EFFECT:  Creates a list of functions used in a term. If no
+           functions are used in a term, it returns an empty 
+	   list.
+***************************************************************/
+{
+  LIST result;
+  LIST scan;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_ListOfFunctions: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  result = list_Nil();
+
+  /* If the term starts with a function, add the function symbol
+     to the result.
+  */
+  if (symbol_IsFunction(term_TopSymbol(Term))) {
+    result = list_Nconc(result, list_List((POINTER) term_TopSymbol(Term)));
+  }
+  
+  /* A function can utilize other functions, so
+     traverse the argument list for further
+     functions.
+  */
+  for (scan = term_ArgumentList(Term); 
+       !list_Empty(scan); 
+       scan = list_Cdr(scan)) {
+    /* Append to the smaller list for efficiency. 
+       A subterm's list of functions will usually 
+       be smaller than the intermediate result.
+    */
+    result = list_Nconc(term_ListOfFunctions((TERM) list_Car(scan)), result);
+  }
+
+  return result;
+}
+
+void term_CountSymbols(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: None.
+  EFFECT:  Counts the non-variable symbols in the term, and 
+           increases their counts accordingly.
+***************************************************************/
+{
+  LIST scan;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_CountSymbols: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  /* If the term starts with a function, increase the count for
+     the function symbol.
+  */
+  if (symbol_IsFunction(term_TopSymbol(Term))) {
+    SYMBOL S;
+
+    S = term_TopSymbol(Term);
+    symbol_SetCount(S, symbol_GetCount(S) + 1);
+  }
+
+  /* A function can utilize other functions, so
+     traverse the argument list for further
+     function symbols.
+  */
+  for (scan = term_ArgumentList(Term); 
+       !list_Empty(scan); 
+       scan = list_Cdr(scan)) {
+    term_CountSymbols((TERM) list_Car(scan));
+  }
+}
+
+static int term_CompareByArity(TERM Left, TERM Right)
+/**************************************************************
+  INPUT:   Two terms.
+  RETURNS:  1 if left term < right term
+            0 if left term = right term
+	   -1 if left term > right term
+  EFFECT:  Terms are compared top down, left to right with 
+           respect to the arity of their signature symbols,
+	   where variables in addition are defined to be smaller
+	   than constants.
+***************************************************************/
+{
+  NAT    lval, rval;
+  SYMBOL lsymb, rsymb;
+  LIST   largs, rargs;
+  int    result;
+
+  result = 0;
+
+  /* Compare top symbols first */
+  lsymb = term_TopSymbol(Left);
+  rsymb = term_TopSymbol(Right);
+
+  if (symbol_IsVariable(lsymb)) {
+    if (symbol_IsVariable(rsymb))
+      return 0;
+    else
+      return 1;
+  }
+  else
+    if (symbol_IsVariable(rsymb))
+      return -1;
+
+  lval = symbol_Arity(lsymb);
+  rval = symbol_Arity(rsymb);
+  
+  if (lval > rval)
+    return -1;
+
+  if (lval < rval)
+    return 1;
+
+  /* If top symbol arities are equal, compare subterms left to right */
+  largs = term_ArgumentList(Left);
+  rargs = term_ArgumentList(Right);
+
+  while(!list_Empty(largs)) {
+    result = term_CompareByArity(list_Car(largs), list_Car(rargs));	
+    if (result != 0)
+      break;
+
+    largs = list_Cdr(largs);
+    rargs = list_Cdr(rargs);
+  }
+
+  return result;
+}
+
+int term_CompareBySymbolOccurences(TERM Left, TERM Right)
+/**************************************************************
+  INPUT:   Two terms.
+  RETURNS:  1 if left term < right term
+            0 if left term = right term
+	   -1 if left term > right term
+  EFFECT:  Terms are compared top down, left to right with 
+           respect to the frequency of their symbols.
+***************************************************************/
+{
+  unsigned long  lval, rval;
+  SYMBOL         lsymb, rsymb;
+  LIST           largs, rargs;
+  int            result;
+
+  result = 0;
+
+  /* Compare top symbols first */
+  lsymb = term_TopSymbol(Left);
+  rsymb = term_TopSymbol(Right);
+
+  if (symbol_IsFunction(lsymb)) {
+    if (symbol_IsFunction(rsymb)) {
+
+      lval = symbol_GetCount(lsymb);
+      rval = symbol_GetCount(rsymb);
+  
+      if (lval > rval)
+	return -1;
+
+      if (lval < rval)
+	return 1;
+    
+      /* If top symbol arities are equal, compare subterms left to right */
+      largs = term_ArgumentList(Left);
+      rargs = term_ArgumentList(Right);
+
+      while(!list_Empty(largs)) {
+	result = term_CompareBySymbolOccurences(list_Car(largs), 
+						list_Car(rargs));	
+	if (result != 0)
+	  break;
+
+	largs = list_Cdr(largs);
+	rargs = list_Cdr(rargs);
+      }
+    }
+    else {
+      return -1;
+    }
+  }
+  else {
+    if (symbol_IsFunction(rsymb)) {
+      return 1;
+    }
+  }
+
+  return result;
+}
+
+int term_CompareAbstract(TERM Left, TERM Right)
+/**************************************************************
+  INPUT:   Two terms.
+  RETURNS:  1 if left term < right term
+            0 if left term = right term
+	   -1 if left term > right term
+  EFFECT:  Compares two terms using an internal array of term 
+           comparison functions. As soon as a term is found to 
+	   compare greater than the other, the result of the 
+	   comparison is returned. If all term comparison 
+	   functions yield an "equal", then 0 is returned.
+***************************************************************/
+{
+  int result;
+  int i;
+  int functions;
+
+  typedef int (*TERM_COMPARE_FUNCTION) (TERM, TERM);
+
+  static const TERM_COMPARE_FUNCTION term_compare_functions [] = {
+    term_CompareByArity,
+    term_CompareBySymbolOccurences,
+    term_CompareByConstants,
+    term_CompareByVariables,
+    term_CompareByFunctions
+  };
+
+#ifdef CHECK
+  if (!(term_IsTerm(Left) && term_IsTerm(Right))) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_CompareAbstract: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  result    = 0;
+  functions = sizeof(term_compare_functions)/sizeof(TERM_COMPARE_FUNCTION);
+
+  for (i = 0; i < functions; i++) {
+    result = term_compare_functions[i](Left, Right);
+
+    if ( result != 0) {
+      return result;
+    }
+  }
+
+  return result;
+}
+
+BOOL term_CompareAbstractLEQ(TERM Left, TERM Right)
+/**************************************************************
+  INPUT:   Two terms.
+  RETURNS: TRUE if left term <= right term, FALSE otherwise.
+  EFFECT:  Terms are compared top down, left to right with 
+           respect to the arity of their signature symbols,
+	   where variables in addition are defined to be smaller
+	   than constants.
+***************************************************************/
+{
+  return (term_CompareAbstract(Left, Right) >= 0);
+}
+
+
+NAT term_ComputeSize(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: The number of symbols in the term.
+  EFFECT:  None
+***************************************************************/
+{
+  NAT  Weight;
+  LIST Scan;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_ComputeSize: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Weight = 1;
+  for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan))
+    Weight += term_ComputeSize((TERM)list_Car(Scan));
+  return Weight;
+}
+
+NAT term_RootDistance(TERM Term)
+/**************************************************************
+  INPUT:   A term with establised father links.
+  RETURNS: The distance from <Term> to its root father term.
+  EFFECT:  None
+***************************************************************/
+{
+  NAT  Distance;
+
+  Distance = 0;
+
+  while (term_Superterm(Term) != (TERM)NULL) {
+    Distance++;
+    Term = term_Superterm(Term);
+  }
+
+  return Distance;
+}
+
+BOOL term_RootDistanceSmaller(TERM Term1, TERM Term2)
+/**************************************************************
+  INPUT:   Two terms with establised father links.
+  RETURNS: TRUE iff root distance of <Term1> is smaller than
+           root distance of <Term2>
+  EFFECT:  None
+***************************************************************/
+{
+  return (term_RootDistance(Term1)<term_RootDistance(Term2));
+}
+
+void term_InstallSize(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: None
+  EFFECT:  Sets for every subterm the size.
+***************************************************************/
+{
+  NAT  Weight;
+  LIST Scan;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_InstallSize: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Weight = 1;
+  for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+    term_InstallSize((TERM)list_Car(Scan));
+    Weight += term_Size((TERM)list_Car(Scan));
+  };
+  term_SetSize(Term, Weight);
+}
+
+NAT term_Depth(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: The depth of the term.
+  EFFECT:  None
+***************************************************************/
+{
+  NAT  Depth,Help;
+  LIST Scan;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_Depth: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Depth = 0;
+  for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+    Help = term_Depth(list_Car(Scan));
+    if (Help > Depth)
+      Depth = Help;
+  }
+  return (Depth+1);
+}
+
+BOOL term_ContainsSymbol(TERM Term, SYMBOL Symbol)
+/**************************************************************
+  INPUT:   A term and a symbol.
+  RETURNS: TRUE, if the symbol occurs somewhere in the term,
+           FALSE otherwise.
+***************************************************************/
+{
+  int Stack;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term) || !symbol_IsSymbol(Symbol)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_ContainsSymbol: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Stack = stack_Bottom();
+
+  do {
+    if (term_TopSymbol(Term) == Symbol) {
+      stack_SetBottom(Stack);    /* Clean up the stack */
+      return TRUE;
+    }
+    else
+      if (term_IsComplex(Term))
+	stack_Push(term_ArgumentList(Term));
+
+    while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+      stack_Pop();
+
+    if (!stack_Empty(Stack)) {
+      Term = list_Car(stack_Top());
+      stack_RplacTop(list_Cdr(stack_Top()));
+    }
+  } while (!stack_Empty(Stack));
+
+  return FALSE;
+}
+
+TERM term_FindSubterm(TERM Term, SYMBOL Symbol)
+/**************************************************************
+  INPUT:   A term and a symbol.
+  RETURNS: If the symbol occurs in the Term the subterm is returned.
+           NULL otherwise.
+***************************************************************/
+{
+  int stack;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term) || !symbol_IsSymbol(Symbol)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_FindSubterm: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  stack = stack_Bottom();
+
+  do {
+    if (term_TopSymbol(Term) == Symbol) {
+      stack_SetBottom(stack);    /* Clean up the stack */
+      return Term;
+    } else if (term_IsComplex(Term))
+      stack_Push(term_ArgumentList(Term));
+
+    while (!stack_Empty(stack) && list_Empty(stack_Top()))
+      stack_Pop();
+
+    if (!stack_Empty(stack)) {
+      Term = list_Car(stack_Top());
+      stack_RplacTop(list_Cdr(stack_Top()));
+    }
+  } while (!stack_Empty(stack));
+
+  return NULL;
+}
+
+static int term_SharingList(TERM Term, LIST List)
+/**************************************************************
+  INPUT:   A term and a list cell.
+  RETURNS: The number of times <List> occurs in <Term>
+  EFFECT:  None
+***************************************************************/
+{
+  LIST Scan;
+  int  n;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_SharingList: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  n = 0;
+
+  for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+    if (Scan == List)
+      n++;
+    n += term_SharingList(list_Car(Scan), List);
+  }
+
+  return n;
+}
+
+
+static int term_SharingTerm(TERM Term, TERM CompareTerm)
+/**************************************************************
+  INPUT:   A term and a compare term
+  RETURNS: The number of occurrences of <CompareTerm> in <Term>
+  EFFECT:  None
+***************************************************************/
+{
+  LIST Scan;
+  int  n;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_SharingTerm: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  n = 0;
+
+  if (Term == CompareTerm)
+    n = 1;
+
+  for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan))
+    n += term_SharingTerm(list_Car(Scan),CompareTerm);
+
+  return n;
+}
+
+
+BOOL term_Sharing(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: TRUE iff the term shares list cells or subterms.
+  EFFECT:  None
+***************************************************************/
+{
+  LIST Scan;
+  int  stack;
+  TERM ActTerm;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_Sharing: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  stack = stack_Bottom();
+  stack_Push(Term);
+
+  while (!stack_Empty(stack)) {
+    ActTerm = (TERM)stack_Top();
+    stack_Pop();
+    
+    if (term_SharingTerm(Term,ActTerm)>1)
+      return TRUE;
+  
+    if (term_IsComplex(Term)) {
+      for (Scan = term_ArgumentList(ActTerm);
+	   !list_Empty(Scan);
+	   Scan=list_Cdr(Scan))
+	if (term_SharingList(Term, Scan) > 1)
+	  return TRUE;
+	else
+	  stack_Push(list_Car(Scan));
+    }
+  }
+  
+  return FALSE;
+}
+
+
+void term_AddFatherLinks(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: void.
+  EFFECT:  The super term links of Term are cleared and then all
+           its subterms are set.
+***************************************************************/
+{
+  LIST Scan;
+  TERM ActTerm;
+
+  term_RplacSuperterm(Term,(TERM)NULL);
+  
+  for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+    ActTerm  = (TERM)list_Car(Scan);
+    term_AddFatherLinks(ActTerm);
+    term_RplacSuperterm(ActTerm,Term);
+  }
+
+}
+
+BOOL term_FatherLinksEstablished(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: TRUE iff all father links in Term are established.
+  EFFECT:  None.
+***************************************************************/
+{
+  LIST Scan;
+  
+  for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+   if (Term != term_Superterm(list_Car(Scan)) || !term_FatherLinksEstablished(list_Car(Scan)))
+     return FALSE;
+
+  return TRUE;
+}
+
+TERM term_TopLevelTerm(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: The top level father of the term.
+  EFFECT:  The father links have to be established!
+***************************************************************/
+{
+  while (term_Superterm(Term))
+    Term = term_Superterm(Term);
+  return Term;
+}
+
+
+BOOL term_HasPointerSubterm(TERM Term, TERM Subterm)
+/**************************************************************
+  INPUT:   Two terms.
+  RETURNS: TRUE, if <Term> has <Subterm> as a subterm.
+  CAUTION: Only term pointers are compared, term_Equal isn't used.
+***************************************************************/
+{
+  if (Term == Subterm)
+    return TRUE;
+  else {
+    LIST scan = term_ArgumentList(Term);
+
+    while (!list_Empty(scan)) {
+      if (term_HasPointerSubterm((TERM) list_Car(scan), Subterm))
+	return TRUE;
+      scan = list_Cdr(scan);
+    }
+  }
+
+  return FALSE;
+}
+
+BOOL term_HasSubterm(TERM Term, TERM Subterm)
+/**************************************************************
+  INPUT:   Two terms.
+  RETURNS: TRUE, if <Term> has <Subterm> as a subterm.
+  CAUTION: term_Equal is used.
+***************************************************************/
+{
+  if (term_Equal(Term,Subterm))
+    return TRUE;
+  else {
+    LIST Scan;
+    Scan = term_ArgumentList(Term);
+
+    while (!list_Empty(Scan)) {
+      if (term_HasSubterm((TERM) list_Car(Scan), Subterm))
+	return TRUE;
+      Scan = list_Cdr(Scan);
+    }
+  }
+
+  return FALSE;
+}
+
+BOOL term_HasProperSuperterm(TERM Term, TERM Super)
+/**********************************************************
+  INPUT   : Two terms.
+  RETURNS : TRUE iff Super can be reached from Term by following
+            the superterm member of the TERM structure.
+  CAUTION : not reflexive
+**********************************************************/
+{
+  if (Term == Super)
+    return FALSE;
+  while (Term != (TERM) NULL) {
+    if (Term == Super)            /* Pointer equality ! */
+      return TRUE;
+    else
+      Term = term_Superterm(Term);
+  }
+  return FALSE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *  TERM OUTPUT FUNCTIONS                                 * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+void term_Print(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: none.
+  SUMMARY: Prints the term to stdout.
+  CAUTION: Uses the other term output functions.
+***************************************************************/
+{
+  if (term_IsComplex(Term)) {
+    putchar('(');
+    symbol_Print(term_TopSymbol(Term));
+    putchar(' ');
+    term_TermListPrint(term_ArgumentList(Term));
+    putchar(')');
+
+  } else if (term_IsVariable(Term)) {
+
+    symbol_Print(term_TopSymbol(Term));
+
+  } else {
+
+    /* term_IsConstant(Term) */
+    putchar('(');
+    symbol_Print(term_TopSymbol(Term));
+    putchar(')');
+  }
+}
+
+static void term_PrettyPrintIntern(TERM Term, int Depth)
+/**************************************************************
+  INPUT:   A term and a depth parameter for indentation.
+  RETURNS: none.
+  SUMMARY: Prints the term hopefully more pretty to stdout.
+***************************************************************/
+{
+  int i;
+  LIST scan;
+
+
+  for (i=0; i < Depth; i++)
+    fputs("  ", stdout);
+  if (symbol_IsJunctor(term_TopSymbol(Term))) {
+    if (term_IsComplex(Term)) {
+      symbol_Print(term_TopSymbol(Term));
+      putchar('(');
+      fputs("\n", stdout);
+      for (scan=term_ArgumentList(Term); !list_Empty(scan); scan= list_Cdr(scan)) {
+	term_PrettyPrintIntern((TERM) list_Car(scan), Depth+1);
+	if (!list_Empty(list_Cdr(scan)))
+	  fputs(",\n", stdout);
+      }
+      putchar(')');
+    }
+    else {
+      if (term_IsVariable(Term)) {
+	symbol_Print(term_TopSymbol(Term));
+      }
+      else {
+	putchar('(');
+	symbol_Print(term_TopSymbol(Term));
+	putchar(')');
+      }
+    }
+  }
+  else {
+    term_PrintPrefix(Term);
+  }
+}
+
+void term_PrettyPrint(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: none.
+  SUMMARY: Prints the term hopefully more pretty to stdout.
+***************************************************************/
+{
+  term_PrettyPrintIntern(Term, 0);
+}
+
+
+void term_FPrint(FILE* File,TERM Term)
+/**************************************************************
+  INPUT:   A file and a term.
+  RETURNS: none.
+  SUMMARY: Prints the term to the file.
+  CAUTION: Uses the other term output functions.
+***************************************************************/
+{
+  if (term_IsComplex(Term)) {
+    putc('(', File);
+    symbol_FPrint(File,term_TopSymbol(Term));
+    putc(' ', File);
+    term_TermListFPrint(File,term_ArgumentList(Term));
+    putc(')', File);
+
+  } else if (term_IsVariable(Term)) {
+
+    symbol_FPrint(File,term_TopSymbol(Term));
+
+  } else {
+
+    /* term_IsConstant(Term) */
+    putc('(', File);
+    symbol_FPrint(File,term_TopSymbol(Term));
+    putc(')', File);
+  }
+}
+
+
+void term_TermListPrint(LIST List)
+/**************************************************************
+  INPUT:   A list of terms.
+  RETURNS: None.
+***************************************************************/
+{
+  for (; !list_Empty(List); List=list_Cdr(List)) {
+    term_Print(list_Car(List)); fflush(stdout);
+    if (!list_Empty(list_Cdr(List)))
+      putchar(' ');
+  }
+}
+
+
+void term_TermListFPrint(FILE* File, LIST List)
+/**************************************************************
+  INPUT:   A list of terms.
+  RETURNS: None.
+***************************************************************/
+{
+  for (; !list_Empty(List); List=list_Cdr(List)) {
+    term_FPrint(File,list_Car(List));
+    if (!list_Empty(list_Cdr(List)))
+      putc(' ', File);
+  }
+}
+
+
+void term_PrintPrefix(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: none.
+  SUMMARY: Prints the term in prefix notation to stdout.
+  CAUTION: Uses the other term output functions.
+***************************************************************/
+{
+  if (term_IsComplex(Term)) {
+    symbol_Print(term_TopSymbol(Term));
+    putchar('(');
+    term_TermListPrintPrefix(term_ArgumentList(Term));
+    putchar(')');
+
+  } else
+    symbol_Print(term_TopSymbol(Term));
+}
+
+
+void term_FPrintPrefix(FILE* File, TERM Term)
+/**************************************************************
+  INPUT:   A file and a term.
+  RETURNS: none.
+  SUMMARY: Prints the term in prefix notation to the file.
+  CAUTION: Uses the other term output functions.
+***************************************************************/
+{
+  if (term_IsComplex(Term)) {
+    symbol_FPrint(File,term_TopSymbol(Term));
+    putc('(', File);
+    term_TermListFPrintPrefix(File,term_ArgumentList(Term));
+    putc(')', File);
+
+  } else
+    symbol_FPrint(File,term_TopSymbol(Term));
+}
+
+
+void term_TermListPrintPrefix(LIST List)
+/**************************************************************
+  INPUT:   A list of terms.
+  RETURNS: None.
+***************************************************************/
+{
+  for (; !list_Empty(List); List=list_Cdr(List)) {
+    term_PrintPrefix(list_Car(List));
+    if (!list_Empty(list_Cdr(List)))
+      putchar(',');
+  }
+}
+
+
+void term_TermListFPrintPrefix(FILE* File, LIST List)
+/**************************************************************
+  INPUT:   A list of terms.
+  RETURNS: None.
+***************************************************************/
+{
+  for (; !list_Empty(List); List=list_Cdr(List)) {
+    term_FPrintPrefix(File,list_Car(List));
+    if (!list_Empty(list_Cdr(List)))
+      putc(',', File);
+  }
+}
+
+
+
+void term_FPrintOtterPrefix(FILE* File, TERM Term)
+/**************************************************************
+  INPUT:   A file and a term.
+  RETURNS: none.
+  SUMMARY: Prints the term in prefix notation to the file.
+  CAUTION: Uses the other term_Output functions.
+***************************************************************/
+{
+  if (term_IsComplex(Term)) {
+    symbol_FPrintOtter(File, term_TopSymbol(Term));
+    putc('(', File);
+    term_TermListFPrintOtterPrefix(File, term_ArgumentList(Term));
+    putc(')', File);
+  } else
+    symbol_FPrintOtter(File, term_TopSymbol(Term));
+}
+
+
+void term_TermListFPrintOtterPrefix(FILE* File, LIST List)
+/**************************************************************
+  INPUT:   A list of terms.
+  RETURNS: None.
+***************************************************************/
+{
+  for (; !list_Empty(List); List=list_Cdr(List)) {
+    term_FPrintOtterPrefix(File,list_Car(List));
+    if (!list_Empty(list_Cdr(List)))
+      putc(',', File);
+  }
+}
+
+
+void term_FPrintPosition(FILE* File, TERM TopTerm, TERM Subterm)
+/**************************************************************
+  INPUT:   An output file and two terms where <Subterm> is a subterm
+           of <TopTerm>.
+  RETURNS: Nothing.
+  SUMMARY: The position of <Subterm> relative to <TopTerm> is
+           printed to the output file. A simple top-down search
+	   is done, so the superterm pointers are not needed.
+	   Note that we compare terms with respect to pointers!
+	   If <Subterm> isn't a subterm of <TopTerm> at all,
+	   this causes an error message followed by a core dump.
+***************************************************************/
+{
+  NAT  pos;
+  LIST Scan;
+
+  if (TopTerm == Subterm)
+    return;
+
+  for (Scan = term_ArgumentList(TopTerm), pos = 1; !list_Empty(Scan);
+       Scan = list_Cdr(Scan), pos++) {
+    if (term_HasPointerSubterm(list_Car(Scan), Subterm)) {
+      fprintf(File, "%u", pos);
+      if (Subterm != list_Car(Scan)) {
+	putc('.', File);
+	term_FPrintPosition(File, list_Car(Scan), Subterm);
+      }
+      return;
+    }
+  }
+  misc_StartErrorReport();
+  misc_ErrorReport("\n In term_FPrintPosition: Term isn't subterm of the other one.");
+  misc_FinishErrorReport();
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *			HIGH LEVEL FUNCTIONS		    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+NAT term_Bytes(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: The number of bytes occupied by the term.
+  EFFECT:  None
+***************************************************************/
+{
+  NAT  Bytes;
+  LIST Scan;
+
+  Bytes = sizeof(TERM_NODE) + list_Bytes(term_ArgumentList(Term));
+  for (Scan=term_ArgumentList(Term); !list_Empty(Scan); Scan=list_Cdr(Scan))
+    Bytes += term_Bytes((TERM)list_Car(Scan));
+  return Bytes;
+}
+
+
+LIST term_ListOfVariables(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: The list of variables occurring in the term.
+           Note that there may be many terms with same variable symbol.
+***************************************************************/
+{
+  LIST         Stack, Variables;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_ListOfVariables: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Variables = list_Nil();
+  Stack     = list_StackBottom();
+  do {
+    if (term_IsComplex(Term))
+      Stack = list_Push(term_ArgumentList(Term),Stack);
+    else
+      if (term_IsVariable(Term))
+	Variables = list_Cons(Term, Variables);
+    while (!list_StackEmpty(Stack) && list_Empty(list_Top(Stack)))
+      Stack = list_Pop(Stack);
+    if (!list_StackEmpty(Stack)) {
+      Term = (TERM)list_Car(list_Top(Stack));
+      list_RplacTop(Stack, list_Cdr(list_Top(Stack)));
+    }
+  } while (!list_StackEmpty(Stack));
+  return Variables;
+}
+
+
+void term_MarkVariables(TERM Term, NAT Mark)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: Nothing.
+  EFFECT:  All variables from <Term> are marked with <Mark>.
+  CAUTION: The term module must be in a binding phase (started with
+           term_StartBinding)!
+***************************************************************/
+{
+  int Stack;
+
+#ifdef CHECK
+  if (!term_InBindingPhase()) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_MarkVariables:");
+    misc_ErrorReport(" Called while not in binding phase.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Stack = stack_Bottom();
+  do {
+    if (term_IsComplex(Term)) {
+      stack_Push(term_ArgumentList(Term));
+    }
+    else if (term_IsVariable(Term))
+      term_CreateBinding(term_TopSymbol(Term), Mark);
+    while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+      stack_Pop();
+    if (!stack_Empty(Stack)) {
+      Term = (TERM)list_Car(stack_Top());
+      stack_RplacTop(list_Cdr(stack_Top()));
+    }
+  } while (!stack_Empty(Stack));
+}
+
+
+LIST term_VariableSymbols(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: The list of variable symbols occurring in the term.
+***************************************************************/
+{
+  LIST    Variables;
+  int     Stack;
+  SYMBOL  Top;
+  NAT     ActMark;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term) || term_InBindingPhase()) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_VariableSymbols: Illegal input or context.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  term_StartBinding();
+
+  Variables = list_Nil();
+  Stack     = stack_Bottom();
+  ActMark   = term_ActMark();
+  do {
+    if (term_IsComplex(Term)) {
+      stack_Push(term_ArgumentList(Term));
+    }
+    else {
+      Top = term_TopSymbol(Term);
+      if (symbol_IsVariable(Top) && !term_VarIsMarked(Top, ActMark)) {
+	Variables = list_Cons((POINTER)Top, Variables);
+	term_CreateBinding(Top, ActMark);
+      }
+    }
+    while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+      stack_Pop();
+    if (!stack_Empty(Stack)) {
+      Term = (TERM)list_Car(stack_Top());
+      stack_RplacTop(list_Cdr(stack_Top()));
+    }
+  } while (!stack_Empty(Stack));
+
+  term_StopBinding();
+
+  return Variables;
+}
+
+
+NAT term_NumberOfVarOccs(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: The list of variable symbols occurring in the term.
+***************************************************************/
+{
+  NAT      Result;
+  int      Stack;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_NumberOfVarOccs: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Result = 0;
+  Stack = stack_Bottom();
+  do {
+    if (term_IsComplex(Term)) {
+      stack_Push(term_ArgumentList(Term));
+    }
+    else {
+      if (symbol_IsVariable(term_TopSymbol(Term)))
+	Result++;
+    }
+    while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+      stack_Pop();
+    if (!stack_Empty(Stack)) {
+      Term = (TERM)list_Car(stack_Top());
+      stack_RplacTop(list_Cdr(stack_Top()));
+    }
+  } while (!stack_Empty(Stack));
+
+  return Result;
+}
+
+NAT term_NumberOfSymbolOccurrences(TERM Term, SYMBOL Symbol)
+/**************************************************************
+  INPUT:   A term and a symbol.
+  RETURNS: The number of occurrences of <Symbol> in <Term>
+***************************************************************/
+{
+  NAT   Result;
+  LIST  Scan;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term) || !symbol_IsSymbol(Symbol)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_NumberOfSymbolOccurrences: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Result = 0;
+  
+  if (symbol_Equal(term_TopSymbol(Term),Symbol))
+    Result++;
+
+  for (Scan = term_ArgumentList(Term); !list_Empty(Scan);  Scan=list_Cdr(Scan))
+    Result += term_NumberOfSymbolOccurrences(list_Car(Scan), Symbol);
+
+  return Result;
+}
+
+
+BOOL term_ContainsFunctions(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: TRUE iff the term contains a function symbol
+***************************************************************/
+{
+  int      Stack;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_ContainsFunctions: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Stack = stack_Bottom();
+  do {
+    if (term_IsComplex(Term)) {
+      if (symbol_IsFunction(term_TopSymbol(Term)) && !symbol_IsConstant(term_TopSymbol(Term))) {
+	stack_SetBottom(Stack);
+	return TRUE;
+      }
+      stack_Push(term_ArgumentList(Term));
+    }
+
+    while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+      stack_Pop();
+    if (!stack_Empty(Stack)) {
+      Term = (TERM)list_Car(stack_Top());
+      stack_RplacTop(list_Cdr(stack_Top()));
+    }
+  } while (!stack_Empty(Stack));
+
+  return FALSE;
+}
+
+BOOL term_ContainsVariable(TERM Term, SYMBOL Var)
+/**************************************************************
+  INPUT:   A term and a variable symbol.
+  RETURNS: TRUE iff the term contains the variable symbol
+***************************************************************/
+{
+  int      Stack;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term) || !symbol_IsSymbol(Var)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_ContainsVariable: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Stack = stack_Bottom();
+  do {
+    if (term_IsComplex(Term))
+      stack_Push(term_ArgumentList(Term));
+    else
+      if (symbol_Equal(term_TopSymbol(Term),Var)) {
+	stack_SetBottom(Stack);
+	return TRUE;
+      }
+
+    while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+      stack_Pop();
+    if (!stack_Empty(Stack)) {
+      Term = (TERM)list_Car(stack_Top());
+      stack_RplacTop(list_Cdr(stack_Top()));
+    }
+  } while (!stack_Empty(Stack));
+
+  return FALSE;
+}
+
+SYMBOL term_MaxVar(TERM Term)
+/*********************************************************
+  INPUT:   A term.
+  RETURNS: The maximal variable in <Term>, NULL otherwise
+********************************************************/
+{
+  LIST   Scan;
+  int    Stack;
+  SYMBOL Result;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_MaxVar: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  Result = (SYMBOL)NULL;
+  Stack  = stack_Bottom();
+
+  if (term_IsStandardVariable(Term)) {
+    if (term_TopSymbol(Term)>Result)
+      Result = term_TopSymbol(Term);
+  }
+  else
+    if (term_IsComplex(Term))
+      stack_Push(term_ArgumentList(Term));
+  
+  while (!stack_Empty(Stack)) {
+    Scan = stack_Top();
+    Term = (TERM)list_Car(Scan);
+    stack_RplacTop(list_Cdr(Scan));
+    
+    if (term_IsStandardVariable(Term)) {
+      if (term_TopSymbol(Term)>Result)
+	Result = term_TopSymbol(Term);
+    }
+    else
+      if (term_IsComplex(Term))
+	stack_Push(term_ArgumentList(Term));
+    
+    while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+      stack_Pop();
+  }
+  
+  return Result;
+}
+
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *			Renaming           		    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+void term_StartMinRenaming(void)
+/**************************************************************
+  INPUT:   None
+  EFFECT:  Initializes the term and symbol modules for min co var renaming
+***************************************************************/
+{
+  symbol_ResetStandardVarCounter();
+  term_NewMark();
+}
+
+
+void term_StartMaxRenaming(SYMBOL MaxVar)
+/**************************************************************
+  INPUT:   A variable symbol.
+  EFFECT:  Initializes the term and symbol modules for renaming above <MaxVar>
+***************************************************************/
+{
+  symbol_SetStandardVarCounter(MaxVar);
+  term_NewMark();
+}
+
+
+TERM term_Rename(TERM Term)
+/**************************************************************
+  INPUT:   A Term.
+  RETURNS: The destructively renamed term.
+  EFFECT:  All co variables are destructively renamed in <TERM>
+***************************************************************/
+{
+  int     Stack;
+  SYMBOL  Top;
+  NAT     ActMark;
+  TERM    ActTerm;
+  
+#ifdef CHECK
+  if (!term_IsTerm(Term) || term_InBindingPhase()) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_Rename: Illegal input or context.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  term_StartBinding();
+  
+  Stack = stack_Bottom();
+  ActMark = term_OldMark();
+  ActTerm = Term;
+  do {
+    if (term_IsComplex(ActTerm)) {
+      stack_Push(term_ArgumentList(ActTerm));
+    }
+    else {
+      Top = term_TopSymbol(ActTerm);
+      if (symbol_IsVariable(Top)) {
+	if (!term_VarIsMarked(Top, ActMark))
+	  term_CreateValueBinding(Top, ActMark, (POINTER)symbol_CreateStandardVariable());
+	term_RplacTop(ActTerm,(SYMBOL)term_BindingValue(Top));
+      }
+    }
+    
+    while (!stack_Empty(Stack) && list_Empty(stack_Top()))
+      stack_Pop();
+    if (!stack_Empty(Stack)) {
+      ActTerm = (TERM)list_Car(stack_Top());
+      stack_RplacTop(list_Cdr(stack_Top()));
+    }
+  } while (!stack_Empty(Stack));
+
+  term_StopBinding();
+  
+  return Term;
+}
+
+SYMBOL term_GetRenamedVarSymbol(SYMBOL Var)
+/**************************************************************
+  INPUT:   A variable symbol.
+  RETURNS: The renamed variable for symbol for <var> with respect
+           to the current renaming. If it does not exist, <var>
+	   itself is returned.
+  EFFECT:  None.
+***************************************************************/
+{
+  NAT ActMark;
+
+#ifdef CHECK
+  if (!symbol_IsStandardVariable(Var)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_GetRenamedVarSymbol: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  ActMark = term_OldMark();
+  
+  if (term_VarIsMarked(Var, ActMark))
+    return (SYMBOL)term_BindingValue(Var);
+
+  return Var;
+}
+
+
+static LIST term_MakePseudoLinear(TERM Term, NAT Depth, NAT Mark)
+/**************************************************************
+  INPUT:   A Term and a variable and the current depth.
+  RETURNS: A list of pairs (<oldvar>,<newvar>)
+  EFFECT:  The term is destructively made pseudo_linear.
+***************************************************************/
+{
+  LIST   Result,Scan;
+  SYMBOL Top;
+
+  Result = list_Nil();
+
+  if (term_IsComplex(Term))
+    for (Scan=term_ArgumentList(Term);!list_Empty(Scan);Scan=list_Cdr(Scan))
+      Result = list_Nconc(term_MakePseudoLinear(list_Car(Scan),Depth+1,Mark),
+			  Result);
+  else {
+    Top = term_TopSymbol(Term);
+    if (symbol_IsVariable(Top)) {
+      if (term_VarIsMarked(Top, Mark)) {
+	if (Depth != (NAT)term_BindingValue(Top))
+	  term_RplacTop(Term,symbol_CreateStandardVariable());
+	Result = list_Cons(list_PairCreate((POINTER)Top,
+					   (POINTER)term_TopSymbol(Term)),
+			   Result);
+      }
+      else {
+	term_CreateValueBinding(Top, Mark, (POINTER)Depth);
+      }
+    }
+  }
+  
+  return Result;
+}
+
+
+LIST term_RenamePseudoLinear(TERM Term, SYMBOL Var)
+/**************************************************************
+  INPUT:   A Term and a variable.
+  RETURNS: A list of pairs (<oldvar>,<newvar>)
+  EFFECT:  The term is destructively renamed.
+***************************************************************/
+{
+  NAT  Mark;
+  LIST Result;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term) || !symbol_IsVariable(Var) || term_InBindingPhase()) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_RenamePseudoLinear: Illegal input or context.");
+    misc_FinishErrorReport();
+  }
+#endif
+  
+  term_StartBinding();
+  symbol_SetStandardVarCounter(Var);
+
+  term_NewMark();
+  Mark   = term_ActMark();
+  Result = term_MakePseudoLinear(Term,0,Mark);
+
+  term_StopBinding();
+
+  return Result;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *			STAMP FUNCTIONS  	            * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+NAT term_GetStampID(void)
+/**************************************************************
+  INPUT:   None
+  RETURNS: An identifier that must be used for some stamp functions
+  EFFECT:  Each module using the term stamp has to request an
+           identifier that is needed for function term_StampOverflow
+           The purpose of this identifier is to synchronize
+           different modules in case of an overflow of the variable
+           term_STAMP.
+***************************************************************/
+{
+  if (term_STAMPUSERS >= term_MAXSTAMPUSERS) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n In term_GetStampID: no more free stamp IDs.");
+    misc_UserErrorReport("\n You have to increase the constant term_MAXSTAMPUSERS.");
+    misc_FinishUserErrorReport();
+  }
+
+  return term_STAMPUSERS++;
+}
+
+
+BOOL term_StampOverflow(NAT ID)
+/**************************************************************
+  INPUT:   The identifier of the calling module as returned by
+           the function term_GetStampID.
+  RETURNS: True if an overflow of the variable term_STAMP occurred
+           for the module with the identifier ID.
+  CAUTION: If an overflow occurred for a module you can test that
+           only once!!! After the first test the overflow flag
+	   is cleared for that module.
+***************************************************************/
+{
+  BOOL Result = FALSE;
+  NAT i;
+
+#ifdef CHECK
+  if (ID >= term_MAXSTAMPUSERS) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_StampOverflow: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  if (term_STAMP == NAT_MAX) {
+    term_STAMP = 0;
+    /* set overflow flag for all other modules */
+    for (i = 0; i < term_MAXSTAMPUSERS; i++)
+      term_STAMPOVERFLOW[i] = TRUE;
+    term_STAMPOVERFLOW[ID] = FALSE;
+    Result = TRUE;
+  } else if (term_STAMPOVERFLOW[ID]) {
+    term_STAMPOVERFLOW[ID] = FALSE;
+    Result = TRUE;
+  }
+  return Result;
+}
+
+void term_SetTermSubtermStamp(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: void.
+  EFFECT:  Sets the current stamp to <Term> and its subterms.
+***************************************************************/
+{
+#ifdef CHECK
+  if (!term_IsTerm(Term)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_SetTermSubtermStamp: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  term_SetTermStamp(Term);
+  list_Apply((void (*)(POINTER)) term_SetTermSubtermStamp,
+	     term_ArgumentList(Term));
+}
+
+LIST term_ListOfAtoms(TERM Term, SYMBOL Predicate)
+/**************************************************************
+  INPUT:   A term and a predicate symbol.
+  RETURNS: A list of pointers to all atoms in Term with
+           predicate symbol <Predicate>.
+***************************************************************/
+{
+  if (symbol_Equal(term_TopSymbol(Term), Predicate))
+    return list_List(Term);
+  else {
+    LIST Result, List;
+
+    Result = list_Nil();
+    for (List = term_ArgumentList(Term); !list_Empty(List); List = list_Cdr(List))
+      Result = list_Nconc(Result, term_ListOfAtoms(list_Car(List), Predicate));
+    return Result;
+  }
+}
+
+/* Currently only in CHECK mode */
+#ifdef CHECK
+
+void term_StartStamp(void)
+/**************************************************************
+  INPUT:   None
+  RETURNS: Nothing
+  EFFECT:  The stamp is prepared for a new term traversal.
+***************************************************************/
+{
+  if (term_STAMPBLOCKED) {
+    /* Error: the Stamp is already used */
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_StartStamp: Illegal context, term stamp is already used.");
+    misc_FinishErrorReport();
+  }
+  else {
+    term_STAMP++;
+    term_STAMPBLOCKED = TRUE;
+  }
+}
+
+#endif
+
+LIST term_FindAllAtoms(TERM Term, SYMBOL Predicate)
+/**********************************************************************
+   INPUT:  A term Term and a symbol Predicate.
+   RETURN: A list of all atoms of Term with Symbol as top symbol.
+***********************************************************************/
+{
+  int stack;
+  LIST Result;
+
+#ifdef CHECK
+  if (!term_IsTerm(Term) || !symbol_IsPredicate(Predicate)) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In term_FindAllPredicates: Illegal input.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  stack  = stack_Bottom();
+  Result = list_Nil();
+
+  do {
+    if (term_TopSymbol(Term) == Predicate) {
+      Result = list_Cons(Term, Result);
+    } else if (term_IsComplex(Term))
+      stack_Push(term_ArgumentList(Term));
+
+    while (!stack_Empty(stack) && list_Empty(stack_Top()))
+      stack_Pop();
+
+    if (!stack_Empty(stack)) {
+      Term = list_Car(stack_Top());
+      stack_RplacTop(list_Cdr(stack_Top()));
+    }
+  } while (!stack_Empty(stack));
+
+  return Result;
+}
+
+BOOL term_CheckTermIntern(TERM Term, BOOL Links)
+/**************************************************************************
+  INPUT:  A term and a boolean.
+  RETURN: True iff  1) the arity of each top symbol is equal to the number
+                       of arguments of symbol's term.
+		and 2) either all father links are set correctly iff Links is TRUE
+		       or none is set iff Links is FALSE.
+  COMMENT: Intern function of term_CheckTerm.
+***************************************************************************/
+{
+  LIST Scan;
+  SYMBOL Top;
+  
+  if (!term_IsTerm(Term))
+    return FALSE;
+
+  Top = term_TopSymbol(Term);
+  if (symbol_IsSignature(Top) &&
+      symbol_Arity(Top) != -1 &&
+      symbol_Arity(Top) != (int)list_Length(term_ArgumentList(Term)))
+    return FALSE;
+
+  if (symbol_IsVariable(Top) && !list_Empty(term_ArgumentList(Term)))
+    return FALSE;
+
+  if (Links) {
+    for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+      if (term_Superterm(list_Car(Scan)) != Term ||
+	  !term_CheckTermIntern(list_Car(Scan), Links))
+	return FALSE;
+    }
+  }
+  else {
+    for (Scan = term_ArgumentList(Term); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+      if (term_Superterm(list_Car(Scan)) != term_Null() ||
+	  !term_CheckTermIntern(list_Car(Scan), Links))
+	return FALSE;
+    }
+  }
+  return TRUE;
+}
+
+BOOL term_CheckTerm(TERM Term)
+/********************************************************************************
+   INPUT : A term Term.
+   RETURN: TRUE iff  eihter all or no father links are set AND
+                     the length of any argument list matches the arity of the respective symbol
+*********************************************************************************/
+{
+  if (term_IsComplex(Term) &&
+      term_Superterm(term_FirstArgument(Term)) != term_Null())
+    /* check father links as well */
+    return term_CheckTermIntern(Term, TRUE);
+  else
+    return term_CheckTermIntern(Term, FALSE);
+}
diff --git a/test/spass/term.h b/test/spass/term.h
new file mode 100644
index 0000000000000000000000000000000000000000..3acb2371197c7224142f2301dc2eeb4b9ac7afea
--- /dev/null
+++ b/test/spass/term.h
@@ -0,0 +1,612 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                       TERMS                            * */
+/* *                                                        * */
+/* *  $Module:   TERM                                       * */
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#ifndef _TERM_
+#define _TERM_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "symbol.h"
+#include "stack.h"
+
+/**************************************************************/
+/* Structures                                                 */
+/**************************************************************/
+
+/* In CHECK mode you can block the stamp for all terms,
+   so no other function can use the macro term_IncStamp(),
+   which must be used for initialization at the beginning
+   of a new traversal */
+
+typedef struct term {
+  SYMBOL symbol;
+  union {
+    LIST termlist;
+    struct term* term;
+  } super;
+  LIST   args;
+  NAT    stamp;
+  NAT    size;
+} *TERM, TERM_NODE;
+
+
+/* Data Structures and Macros for Marking of variables, used in */
+/* all functions extracting variables from terms.               */
+
+extern NAT      term_MARK;
+extern POINTER  term_BIND[symbol__MAXVARIABLES][2];
+
+#ifdef CHECK
+extern BOOL term_BINDPHASE;
+static  __inline__ void term_StartBinding(void)   { term_BINDPHASE=TRUE; }
+static  __inline__ void term_StopBinding(void)    { term_BINDPHASE=FALSE; }
+static  __inline__ BOOL term_InBindingPhase(void) { return term_BINDPHASE; }
+#else
+static  __inline__ void term_StartBinding(void)   { }
+static  __inline__ void term_StopBinding(void)    { }
+#endif
+
+static __inline__ NAT term_NullMark(void)
+{
+  return 0;
+}
+
+
+static __inline__ NAT term_BindingMark(SYMBOL Var)
+{
+  return (NAT) term_BIND[symbol_VarIndex(Var)][0];
+}
+
+
+static __inline__ void term_SetBindingMark(SYMBOL Var, NAT Mark)
+{
+  term_BIND[symbol_VarIndex(Var)][0] = (POINTER) Mark;
+}
+
+
+static __inline__ POINTER term_BindingValue(SYMBOL Var)
+{
+  return term_BIND[symbol_VarIndex(Var)][1];
+}
+
+
+static __inline__ void term_SetBindingValue(SYMBOL Var, POINTER Value)
+{
+  term_BIND[symbol_VarIndex(Var)][1] = Value;
+}
+
+static __inline__ void term_CreateBinding(SYMBOL Var, NAT Mark)
+{
+  term_SetBindingMark(Var, Mark);
+}
+
+static __inline__ void term_ClearBinding(SYMBOL Var)
+{
+  term_SetBindingMark(Var, term_NullMark());
+}
+
+static __inline__ void term_CreateValueBinding(SYMBOL Var, NAT Mark, POINTER Value)
+{
+  term_SetBindingMark(Var, Mark);
+  term_SetBindingValue(Var, Value);
+}
+
+
+static __inline__ BOOL term_VarIsMarked(SYMBOL Var, NAT Mark)
+{
+  return term_BindingMark(Var) >= Mark;
+}
+
+
+static __inline__ NAT term_ActMark(void)
+{
+  NAT MarkVar;
+  if (term_MARK == NAT_MAX) {
+    int i;
+    for (i = 0; i < symbol_MaxVars(); i++)
+      term_BIND[i][0] = (POINTER) term_NullMark();
+    term_MARK = 1;
+  }
+  MarkVar = term_MARK++;
+  return MarkVar;
+}
+
+
+static __inline__ void term_NewMark(void)
+{
+  if (term_MARK == NAT_MAX) {
+    int i;
+    for (i = 0; i < symbol_MaxVars(); i++)
+      term_BIND[i][0] = (POINTER) term_NullMark();
+    term_MARK = 1;
+  }
+  term_MARK++;
+}
+
+
+static __inline__ NAT term_OldMark(void)
+{
+  return term_MARK - 1;
+}
+
+
+/**************************************************************/
+/* Macros                                                     */
+/**************************************************************/
+
+static __inline__ TERM term_Null(void)
+{
+ return (TERM)NULL;
+}
+
+static __inline__ SYMBOL term_TopSymbol(TERM T)
+{
+  return T->symbol;
+}
+
+
+static __inline__ void term_RplacTop(TERM T, SYMBOL S)
+{
+  T->symbol = S;
+}
+
+
+static __inline__ LIST term_SupertermList(TERM T)
+{
+  return T->super.termlist;
+}
+
+
+static __inline__ void term_RplacSupertermList(TERM T, LIST L)
+{
+  T->super.termlist = L;
+}
+
+
+static __inline__ LIST term_AtomsLiterals(TERM T)
+{
+  return T->super.termlist;
+}
+
+
+static __inline__ TERM term_Superterm(TERM T)
+{
+  return T->super.term;
+}
+
+
+static __inline__ void term_RplacSuperterm(TERM T1, TERM T2)
+{
+  T1->super.term = T2;
+}
+
+
+static __inline__ BOOL term_IsVariable(TERM T)
+{
+  return symbol_IsVariable(term_TopSymbol(T));
+}
+
+
+static __inline__ BOOL term_IsStandardVariable(TERM T)
+{
+  return symbol_IsStandardVariable(term_TopSymbol(T));
+}
+
+
+static __inline__ BOOL term_IsIndexVariable(TERM T)
+{
+  return symbol_IsIndexVariable(term_TopSymbol(T));
+}
+
+
+static __inline__ LIST term_ArgumentList(TERM T)
+{
+  return T->args;
+}
+
+
+static __inline__ void term_RplacArgumentList(TERM T, LIST A)
+{
+  T->args = A;
+}
+
+
+static __inline__ BOOL term_IsComplex(TERM T)
+{
+  return term_ArgumentList(T) != NULL;
+}
+
+
+static __inline__ BOOL term_IsConstant(TERM T)
+{
+  return !term_IsComplex(T) && !term_IsVariable(T);
+}
+
+
+static __inline__ BOOL term_IsAtom(TERM T)
+{
+  return symbol_IsPredicate(term_TopSymbol(T));
+}
+
+static __inline__ BOOL term_IsDeclaration(TERM Term)
+/**************************************************************
+  INPUT:   A term.
+  RETURNS: TRUE, if the term is a monadic atom, FALSE otherwise.
+***************************************************************/
+{
+  return (term_IsAtom(Term) && symbol_IsBaseSort(term_TopSymbol(Term)));
+}
+
+
+static __inline__ TERM term_FirstArgument(TERM T)
+{
+  return (TERM) list_First(T->args);
+}
+
+
+static __inline__ void term_RplacFirstArgument(TERM T1, TERM T2)
+{
+  list_Rplaca(T1->args, T2);
+}
+
+
+static __inline__ TERM term_SecondArgument(TERM T)
+{
+  return (TERM) list_Second(T->args);
+}
+
+
+static __inline__ void term_RplacSecondArgument(TERM T1, TERM T2)
+{
+  list_RplacSecond(T1->args, T2);
+}
+
+
+static __inline__ void term_Free(TERM T)
+{
+  memory_Free((char*) T, sizeof(TERM_NODE));
+}
+
+
+static __inline__ BOOL term_EqualTopSymbols(TERM T, TERM S)
+{
+  return symbol_Equal(term_TopSymbol(T), term_TopSymbol(S));
+}
+
+
+static __inline__ void term_EqualitySwap(TERM T)
+{
+  TERM Aux;
+  Aux = term_FirstArgument(T);
+  list_Rplaca(term_ArgumentList(T), (POINTER) term_SecondArgument(T));
+  list_Rplaca(list_Cdr(term_ArgumentList(T)), (POINTER) Aux);
+}
+
+
+/**************************************************************/
+/* Macros and Variables for the term's stamp                  */
+/**************************************************************/
+
+/* Maximum number of modules that use the term module's stamp */
+#define term_MAXSTAMPUSERS  20
+
+extern NAT  term_STAMP;
+extern BOOL term_STAMPBLOCKED;
+
+static __inline__ NAT term_Stamp(void)
+{
+  return term_STAMP;
+}
+
+static __inline__ BOOL term_StampBlocked(void)
+{
+  return term_STAMPBLOCKED;
+}
+
+
+#ifdef CHECK
+
+/* In CHECK mode 'term_StartStamp' is a real function defined in    */
+/* 'term.c'.                                                        */
+
+static __inline__ void term_StopStamp(void)
+{
+  term_STAMPBLOCKED = FALSE;
+}
+
+#else
+
+/* Attention:                                                       */
+/* You should check for Overflow before calling this function !!!!! */
+/* Use "term_StampOverflow" to do this.                             */
+/* If an overflow occurred, you have to reset the stamp of all terms */
+/* you're using.                                                    */
+static __inline__ void term_StartStamp(void)
+{
+  term_STAMP++;
+}
+
+static __inline__ void term_StopStamp(void)
+{ }
+
+#endif
+
+
+static __inline__ NAT term_TermStamp(TERM T)
+{
+  return T->stamp;
+}
+
+static __inline__ void term_SetTermStamp(TERM T)
+{
+  T->stamp = term_STAMP;
+}
+
+static __inline__ NAT term_Size(TERM T)
+{
+  return T->size;
+}
+
+static __inline__ void term_SetSize(TERM T, NAT s)
+{
+  T->size = s;
+}
+
+static __inline__ BOOL term_AlreadyVisited(TERM T)
+{
+  return T->stamp == term_STAMP;
+}
+
+static __inline__ BOOL term_HasTermStamp(TERM T)
+{
+  return T->stamp == term_STAMP;
+}
+
+static __inline__ void  term_ResetTermStamp(TERM T)
+{
+  T->stamp = 0;
+}
+
+static __inline__ BOOL term_StampAlreadyReset(TERM T)
+{
+  return T->stamp == 0;
+}
+
+
+/**************************************************************/
+/* Functions on Term Creation And Deletion                    */
+/**************************************************************/
+
+void  term_Init(void);
+
+TERM  term_Create(SYMBOL, LIST);
+TERM  term_CreateAddFather(SYMBOL, LIST);
+TERM  term_CreateStandardVariable(void);
+void  term_Delete(TERM);
+void  term_DeleteIterative(TERM);
+
+/**************************************************************/
+/* Term Comparisons                                           */
+/**************************************************************/
+
+BOOL  term_Equal(TERM, TERM);
+BOOL  term_EqualIterative(TERM, TERM);               /* Unused */
+BOOL  term_VariableEqual(TERM, TERM);
+BOOL  term_IsGround(TERM);
+BOOL  term_IsTerm(TERM);
+BOOL  term_IsTermList(LIST);
+BOOL  term_AllArgsAreVar(TERM);
+int   term_CompareBySymbolOccurences(TERM, TERM);
+int   term_CompareAbstract(TERM, TERM);
+BOOL  term_CompareAbstractLEQ(TERM, TERM);
+
+
+/**************************************************************/
+/* Low Level Term Functions                                   */
+/**************************************************************/
+
+TERM  term_Copy(TERM);
+TERM  term_CopyIterative(TERM);                     /* Unused */
+TERM  term_CopyWithEmptyArgListNode(TERM, LIST, LIST*);
+void  term_PrintWithEmptyArgListNode(TERM);
+BOOL  term_ReplaceSubtermBy(TERM, TERM, TERM);
+void  term_ReplaceVariable(TERM, SYMBOL, TERM);
+void  term_ExchangeVariable(TERM, SYMBOL, SYMBOL);
+BOOL  term_SubstituteVariable(SYMBOL, TERM, TERM*);
+NAT   term_ComputeSize(TERM);
+void  term_InstallSize(TERM);
+NAT   term_Depth(TERM);
+BOOL  term_ContainsSymbol(TERM, SYMBOL);
+BOOL  term_Sharing(TERM);
+void  term_AddFatherLinks(TERM);
+BOOL  term_FatherLinksEstablished(TERM);
+TERM  term_TopLevelTerm(TERM);
+BOOL  term_HasPointerSubterm(TERM, TERM);
+BOOL  term_HasSubterm(TERM, TERM);
+BOOL  term_HasProperSuperterm(TERM, TERM);
+TERM  term_FindSubterm(TERM, SYMBOL);
+LIST  term_FindAllAtoms(TERM, SYMBOL);
+BOOL  term_CheckTerm(TERM);
+NAT   term_RootDistance(TERM);
+BOOL  term_RootDistanceSmaller(TERM,TERM);
+
+static __inline__ LIST term_CopyTermList(LIST List)
+/**************************************************************
+  INPUT:   A list of TERMs.
+  RETURNS: A deep copy of the list, i.e. the terms are copied, too.
+***************************************************************/
+{
+  return list_CopyWithElement(List, (POINTER (*)(POINTER))term_Copy);
+}
+
+static __inline__ void term_CopyTermsInList(LIST List)
+/**************************************************************
+  INPUT:   A list of TERMs.
+  EFFECT:  Replaces every term in the list with its copy. 
+***************************************************************/
+{
+  list_NMapCar(List, (POINTER (*)(POINTER)) term_Copy);
+}
+
+static __inline__ void term_DeleteTermList(LIST List)
+/**************************************************************
+  INPUT:   A list of TERMs.
+  RETURNS: Nothing.
+  EFFECT:  The list is freed together with its elements.
+***************************************************************/
+{
+  list_DeleteWithElement(List, (void (*)(POINTER))term_Delete);
+}
+
+static __inline__ BOOL term_ListContainsTerm(LIST List, TERM Term)
+/**************************************************************
+  INPUT:   A list of TERMs.
+  RETURNS: TRUE, if <List> contains <Term>, FALSE otherwise.
+           Terms are compared with respect to the term_Equal function.
+***************************************************************/
+{
+  return list_Member(List, Term, (BOOL (*)(POINTER,POINTER))term_Equal);
+}
+
+static __inline__ LIST term_DeleteDuplicatesFromList(LIST List)
+/**************************************************************
+  INPUT:   A list of TERMs.
+  RETURNS: The list where duplicate terms are removed.
+  EFFECT:  Terms are compared with respect to the term_Equal function.
+           The duplicate terms are not deleted.
+***************************************************************/
+{
+  return list_DeleteDuplicates(List, (BOOL (*)(POINTER, POINTER))term_Equal);
+}
+
+
+static __inline__ LIST term_DestroyDuplicatesInList(LIST Terms)
+/**************************************************************
+  INPUT:   A list of terms.
+  RETURNS: The list where all duplicate terms are removed.
+  EFFECTS: The terms are compared with respect to the term_Equal function.
+           The duplicate terms are deleted, too.
+***************************************************************/
+{
+  return list_DeleteDuplicatesFree(Terms, (BOOL (*)(POINTER,POINTER))term_Equal,
+				   (void (*)(POINTER))term_Delete);
+}
+
+
+
+/**************************************************************/
+/* Term Input and Output Functions                            */
+/**************************************************************/
+
+void   term_Print(TERM);
+void   term_PrettyPrint(TERM);
+void   term_FPrint(FILE*, TERM);
+void   term_TermListPrint(LIST);
+void   term_TermListFPrint(FILE*, LIST);
+
+
+void   term_PrintPrefix(TERM);
+void   term_FPrintPrefix(FILE*, TERM);
+void   term_TermListPrintPrefix(LIST);
+void   term_TermListFPrintPrefix(FILE*, LIST);
+
+void   term_FPrintOtterPrefix(FILE*, TERM);
+void   term_TermListFPrintOtterPrefix(FILE*, LIST);
+
+void   term_FPrintPosition(FILE*,TERM,TERM);
+
+static __inline__ void term_PrintPosition(TERM TopTerm, TERM Subterm)
+{
+  term_FPrintPosition(stdout, TopTerm, Subterm);
+}
+
+/**************************************************************/
+/* High Level Term Functions                                  */
+/**************************************************************/
+
+void   term_ToCoVariables(TERM);
+NAT    term_Bytes(TERM);
+
+void   term_MarkVariables(TERM, NAT);
+void   term_CountSymbols(TERM);
+LIST   term_ListOfVariables(TERM);
+LIST   term_VariableSymbols(TERM);
+LIST   term_ListOfAtoms(TERM,SYMBOL);
+LIST   term_ListOfConstants(TERM);
+LIST   term_ListOfFunctions(TERM);
+NAT    term_NumberOfVarOccs(TERM);
+NAT    term_NumberOfSymbolOccurrences(TERM, SYMBOL);
+BOOL   term_ContainsFunctions(TERM);
+BOOL   term_ContainsVariable(TERM,SYMBOL);
+SYMBOL term_MaxVar(TERM);
+
+void   term_StartMinRenaming(void);
+void   term_StartMaxRenaming(SYMBOL);
+TERM   term_Rename(TERM);
+SYMBOL term_GetRenamedVarSymbol(SYMBOL);
+
+LIST   term_RenamePseudoLinear(TERM, SYMBOL);
+
+/**************************************************************/
+/* Stamp Functions                                            */
+/**************************************************************/
+
+/* Currently only in CHECK mode */
+#ifdef CHECK
+void   term_StartStamp(void);
+#endif
+
+void   term_SetTermSubtermStamp(TERM T);
+
+NAT    term_GetStampID(void);
+BOOL   term_StampOverflow(NAT);
+
+
+#endif
diff --git a/test/spass/terminator.c b/test/spass/terminator.c
new file mode 100644
index 0000000000000000000000000000000000000000..73352043745062e19bccbc46a03d95eba1f3a55c
--- /dev/null
+++ b/test/spass/terminator.c
@@ -0,0 +1,319 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                TERMINATOR                              * */
+/* *                                                        * */
+/* *  $Module:   REDRULES                                   * */
+/* *                                                        * */
+/* *  Copyright (C) 1999, 2000, 2001 MPI fuer Informatik    * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* $RCSfile$ */
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "terminator.h"
+#include "list.h"
+
+
+static LIST red_GetTerminatorPartnerLits(TERM Atom, LITERAL Lit,
+					 BOOL UnitsOnly, LIST IndexList)
+/**************************************************************
+  INPUT:   An atom, a literal, a boolean flag and a list of SHARED_INDEXes.
+  RETURNS: A list of literals with sign complementary to <Lit>
+           that are unifiable with <Atom>. The literals are searched
+           in all SHARED_INDEXes from <IndexList>. Additionally,
+           if <Unitsonly> is true, only literals from unit clauses
+	   are returned.
+  EFFECT:  <Atom> is a copy of <Lit> where some substitution
+           was applied and equality literals might have been swapped.
+	   <Lit> is just needed to check whether the unifiable
+	   literals are complementary.
+***************************************************************/
+{
+  LIST    Result, Unifiers, LitScan;
+  LITERAL NextLit;
+
+  Result   = list_Nil();
+  for ( ; !list_Empty(IndexList); IndexList = list_Cdr(IndexList)) {
+    Unifiers = st_GetUnifier(cont_LeftContext(),
+			     sharing_Index(list_Car(IndexList)),
+			     cont_RightContext(), Atom);
+    for ( ; !list_Empty(Unifiers); Unifiers = list_Pop(Unifiers)) {
+      if (!term_IsVariable(list_Car(Unifiers))) {
+	for (LitScan = sharing_NAtomDataList(list_Car(Unifiers));
+	     !list_Empty(LitScan); LitScan = list_Cdr(LitScan)) {
+	  NextLit = list_Car(LitScan);
+	  if (clause_LiteralsAreComplementary(Lit, NextLit) &&
+	      (!UnitsOnly || clause_Length(clause_LiteralOwningClause(NextLit))==1))
+	    /* The partner literals must have complementary sign and
+	       if <UnitsOnly> == TRUE they must be from unit clauses. */
+	    Result = list_Cons(NextLit, Result);
+	}
+      }
+    }
+  }
+  return Result;
+}
+
+
+static CLAUSE red_CreateTerminatorEmptyClause(LIST FoundMap, FLAGSTORE Flags,
+					      PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A list of pairs (l1, l2), where l1 and l2 are unifiable
+           literals with complementary sign and a flag store.
+	   More accurately, a substitution s exists,
+	   such that l1 s = l2 s for all pairs (l1,l2) in
+	   <FoundMap>.
+	   For all literals l from the involved clauses
+	   there exists one pair (l1,l2) in <FoundMap>
+	   with l1=l or l2=l.
+	   The flags store and the precedence are needed to create
+	   the new clause.
+  RETURNS: A newly created empty clause, where the data
+           (parents,...) is set according to <FoundMap>.
+***************************************************************/
+{
+  CLAUSE  Result, PClause;
+  LITERAL Lit;
+  LIST    Parents;
+  NAT     depth;
+
+  Result  = clause_Create(list_Nil(), list_Nil(), list_Nil(), Flags, Precedence);
+  Parents = list_Nil();
+  depth   = 0;
+  for (; !list_Empty(FoundMap); FoundMap = list_Cdr(FoundMap)) {
+    Lit     = list_PairSecond(list_Car(FoundMap));
+    PClause = clause_LiteralOwningClause(Lit);
+    Parents = list_Cons(PClause, Parents);
+    depth   = misc_Max(depth, clause_Depth(PClause));
+    clause_AddParentClause(Result, clause_Number(PClause));
+    clause_AddParentLiteral(Result, clause_LiteralGetIndex(Lit));
+
+    Lit     = list_PairFirst(list_Car(FoundMap));
+    PClause = clause_LiteralOwningClause(Lit);
+    Parents = list_Cons(PClause, Parents);
+    depth   = misc_Max(depth, clause_Depth(PClause));
+    clause_AddParentClause(Result, clause_Number(PClause));
+    clause_AddParentLiteral(Result, clause_LiteralGetIndex(Lit));
+  }
+  clause_SetFromTerminator(Result);
+  clause_SetDepth(Result, depth+1);
+  clause_SetSplitDataFromList(Result, Parents);
+  list_Delete(Parents);
+  return Result;
+}
+
+
+static BOOL red_TerminatorLitIsBetter(LITERAL L1, NAT S1, LITERAL L2, NAT S2)
+/**************************************************************
+  INPUT:   Two literals and its sizes wrt. some substitution.
+  RETURNS: TRUE, if <L1> is 'better' than <L2>, FALSE otherwise.
+  EFFECT:  1. Positive literals are 'better' than negative literals
+           2. If both literals have the same sign, the bigger literal
+	      is better.
+	   This is an heuristic that has shown to be useful in practice.
+	   This function is used as parameter for the function
+	   clause_MoveBestLiteralToFront.
+***************************************************************/
+{
+  if ((clause_LiteralIsNegative(L2) && clause_LiteralIsPositive(L1)) ||
+      /* The following conditions do the same as this condition: */
+      /* (!clause_LiteralsAreComplementary(L1, L2) && S1 > S2)   */
+      (clause_LiteralIsPositive(L1) && S1 > S2) ||
+      (clause_LiteralIsNegative(L2) && S1 > S2))
+    return TRUE;
+  else
+    return FALSE;
+}
+
+
+static CLAUSE red_SearchTerminator(NAT n, LIST RestLits, LIST FoundMap,
+				   SUBST Subst, SYMBOL GlobalMaxVar,
+				   LIST IndexList, FLAGSTORE Flags,
+				   PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A natural number, a list of literals, a list of pairs,
+           a substitution, the maximum variable occurring in all
+	   involved clauses, a list of SHARED_INDEXes, a flag store
+	   and a precedence.
+  RETURNS: An empty clause, if a terminator situation was found,
+           NULL otherwise.
+  EFFECT:  This recursive function implements the search for
+           a terminator situation with at most <n> non-unit clauses.
+	   <RestLits> is the lists of literals actually missing
+	   a complementary partner literal.
+	   <FoundMap> is a list of pairs (l1,l2), where l1 and l2
+	   are complementary, unifiable literals.
+	   <Subst> is the common substitution of all those pairs.
+	   <GlobalMaxVar> is the maximum variable from all
+	   involved clauses.
+	   To enable the search all involved clauses are made
+	   variable-disjoint.
+	   At the moment the function stops, if ANY terminator
+	   situation occurred. This might not be desirable
+	   if splitting is enabled, since there might be other
+	   terminator situations resulting in an empty clause
+	   of lower split level.
+	   The flag store and the precedence are needed to create
+	   the new clause.
+***************************************************************/
+{
+  if (list_Empty(RestLits)) {
+    /* We found a terminator situation, so stop the recursion */
+    return red_CreateTerminatorEmptyClause(FoundMap, Flags, Precedence);
+  } else {
+    CLAUSE  Result, PClauseCopy;
+    LITERAL Lit, PLit;
+    SYMBOL  NewMaxVar;
+    SUBST   NewSubst, RightSubst;
+    TERM    AtomCopy;
+    LIST    ClashList, ToDoList;
+    BOOL    Swapped;
+    NAT     Limit;
+    int     PLitInd;
+
+    Swapped   = FALSE;
+    Result    = clause_Null();
+    clause_MoveBestLiteralToFront(RestLits, Subst, GlobalMaxVar,
+				  red_TerminatorLitIsBetter);
+    Lit       = list_Car(RestLits);
+    RestLits  = list_Cdr(RestLits);
+    AtomCopy  = subst_Apply(Subst, term_Copy(clause_LiteralAtom(Lit)));
+
+    /* The following 'endless' loop runs twice for equality literals */
+    /* and only once for other literals.                             */
+    while (TRUE) {
+      ClashList = red_GetTerminatorPartnerLits(AtomCopy, Lit, n==0, IndexList);
+      for (; !list_Empty(ClashList) && Result==NULL;
+	   ClashList = list_Pop(ClashList)) {
+	PLit        = list_Car(ClashList);
+	PLitInd     = clause_LiteralGetIndex(PLit);
+	PClauseCopy = clause_Copy(clause_LiteralOwningClause(PLit));
+	Limit       = clause_Length(PClauseCopy) == 1 ? n : n-1;
+	
+	clause_RenameVarsBiggerThan(PClauseCopy, GlobalMaxVar);
+	
+	PLit        = clause_GetLiteral(PClauseCopy, PLitInd);
+	FoundMap    = list_Cons(list_PairCreate(Lit, PLit), FoundMap);
+	ToDoList    = clause_GetLiteralListExcept(PClauseCopy, PLitInd);
+	ToDoList    = list_Nconc(ToDoList, list_Copy(RestLits));
+	
+	NewMaxVar   = clause_SearchMaxVar(PClauseCopy);
+	if (symbol_GreaterVariable(GlobalMaxVar, NewMaxVar))
+	  NewMaxVar = GlobalMaxVar;
+	
+	cont_Check();
+	if (!unify_UnifyNoOC(cont_LeftContext(), AtomCopy,
+			     cont_RightContext(), clause_LiteralAtom(PLit))) {
+	  misc_StartErrorReport();
+	  misc_ErrorReport("\n In red_SearchTerminator: Unification failed.");
+	  misc_FinishErrorReport();
+	}
+	subst_ExtractUnifier(cont_LeftContext(), &NewSubst,
+			     cont_RightContext(), &RightSubst);
+	cont_Reset();
+	
+	/* The domains of both substitutions are disjoint */
+	/* so we do just a simple union operation.        */
+	NewSubst = subst_NUnion(NewSubst, RightSubst);
+	RightSubst = NewSubst;
+	NewSubst  = subst_Compose(NewSubst, subst_Copy(Subst));
+	subst_Delete(RightSubst);
+	
+	Result = red_SearchTerminator(Limit, ToDoList, FoundMap, NewSubst,
+				      NewMaxVar, IndexList, Flags, Precedence);
+	
+	clause_Delete(PClauseCopy);
+	subst_Delete(NewSubst);
+	list_Delete(ToDoList);
+	list_PairFree(list_Car(FoundMap));
+	FoundMap = list_Pop(FoundMap);
+      }
+      /* loop control */
+      if (!fol_IsEquality(AtomCopy) || Swapped || Result!=NULL)
+	break;
+      else {
+	list_Delete(ClashList);
+	term_EqualitySwap(AtomCopy);
+	Swapped = TRUE;
+      }
+    }
+    /* cleanup */
+    term_Delete(AtomCopy);
+    /* <ClashList> may be non-empty since the loop stops */
+    /* if a terminator was found.                       */
+    list_Delete(ClashList);
+    
+    return Result;
+  }
+}
+
+
+CLAUSE red_Terminator(CLAUSE RedClause, NAT n, SHARED_INDEX WoIndex,
+		      SHARED_INDEX UsIndex, FLAGSTORE Flags,
+		      PRECEDENCE Precedence)
+/**************************************************************
+  INPUT:   A clause, two shared indexes, a number <n>
+           restricting the number of non-unit clauses in
+	   a possible terminator situation, a flag store
+	   and a precedence.
+  RETURNS: An empty clause if a terminator with at most <n>
+           non-unit clauses is found, NULL otherwise.
+  EFFECT:  See also description of red_SearchTerminator.
+***************************************************************/
+{
+  LIST   Rest, IndexList;
+  CLAUSE Result;
+
+  if (clause_Length(RedClause) > 1)  /* non-unit clause */
+    n--;
+
+  /* Pass the indexes as a list to sub-functions */
+  IndexList = list_Cons(WoIndex, list_List(UsIndex));
+  Rest      = clause_GetLiteralList(RedClause);
+  Result    = red_SearchTerminator(n, Rest, list_Nil(), subst_Nil(),
+				   clause_MaxVar(RedClause), IndexList, Flags,
+				   Precedence);
+  
+  /* cleanup */
+  list_Delete(IndexList);
+  list_Delete(Rest);
+
+  return Result;
+}
diff --git a/test/spass/terminator.h b/test/spass/terminator.h
new file mode 100644
index 0000000000000000000000000000000000000000..8ddf32d3b1fe4510c3e1ffb945bb994635561639
--- /dev/null
+++ b/test/spass/terminator.h
@@ -0,0 +1,58 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                TERMINATOR                              * */
+/* *                                                        * */
+/* *  $Module:   REDRULES                                   * */
+/* *                                                        * */
+/* *  Copyright (C) 1999, 2000, 2001 MPI fuer Informatik    * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+/* $RCSfile$ */
+
+#ifndef _TERMINATOR_
+#define _TERMINATOR_
+
+
+#include "misc.h"
+#include "symbol.h"
+#include "clause.h"
+#include "sharing.h"
+#include "flags.h"
+
+CLAUSE red_Terminator(CLAUSE,NAT,SHARED_INDEX,SHARED_INDEX,FLAGSTORE,PRECEDENCE);
+
+#endif
diff --git a/test/spass/top.c b/test/spass/top.c
new file mode 100644
index 0000000000000000000000000000000000000000..073add9a4bcdf43a44d4fe85205f7450bb494ab8
--- /dev/null
+++ b/test/spass/top.c
@@ -0,0 +1,1648 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *              TOP MODULE OF SPASS                       * */
+/* *                                                        * */
+/* *  $Module:   TOP                                        * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001      * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 35442 $                                       * */
+/* $State$                                            * */
+/* $Date: 2007-03-28 17:24:40 -0700 (Wed, 28 Mar 2007) $                             * */
+/* $Author: jeffc $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+/*** MAIN LOOP *************************************************/
+
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "dfg.h"
+#include "defs.h"
+#include "ia.h"
+#include "rules-inf.h"
+#include "rules-sort.h"
+#include "rules-split.h"
+#include "terminator.h"
+#include "rules-red.h"
+#include "analyze.h"
+#include "clock.h"
+#include "stringsx.h"
+#include "options.h"
+#include "context.h"
+#include "cnf.h"
+#include "search.h"
+#include "hasharray.h"
+#include "closure.h"
+#include <errno.h>
+#include <stdlib.h>
+
+
+/**************************************************************/
+/* Types and Variables                                        */
+/**************************************************************/
+
+static const char *top_InputFile;
+
+static OPTID top_RemoveFileOptId;
+
+typedef enum {top_PROOF, top_COMPLETION, top_RESOURCE} top_SEARCHRESULT;
+
+
+/**************************************************************/
+/* Catch Signals Section                                      */
+/**************************************************************/
+
+#if (defined(SPASS_SIGNALS))
+#include <signal.h>
+
+static PROOFSEARCH *top_PROOFSEARCH;
+
+static void top_SigHandler(int Signal)
+/**************************************************************
+  INPUT:   
+  RETURNS: 
+  EFFECT:  
+***************************************************************/
+{
+  if (Signal == SIGSEGV || Signal == SIGBUS) {
+    puts("\n\n\tSPASS is going to crash. This is probably caused by a");
+    puts("\tbug in SPASS.  Please send a copy of the input file(s) together");
+    puts("\twith the used options to weidenb@mpi-sb.mpg.de, and someone will");
+    puts("\ttry to fix the problem.\n");
+    abort();
+  }
+
+  if (Signal == SIGINT || Signal == SIGTERM) {
+    clock_StopPassedTime(clock_OVERALL);
+    printf("\nSPASS %s ", misc_VERSION);
+    puts("\nSPASS beiseite: Ran out of time. SPASS was killed.");
+    printf("Problem: %s ", 
+	   (top_InputFile != (char*)NULL ? top_InputFile : "Read from stdin."));
+    printf("\nSPASS derived %d clauses, backtracked %d clauses "
+	   "and kept %d clauses.",
+	   (*top_PROOFSEARCH == (PROOFSEARCH)NULL ? 0 : prfs_DerivedClauses(*top_PROOFSEARCH)),
+	   (*top_PROOFSEARCH == (PROOFSEARCH)NULL ? 0 : prfs_BacktrackedClauses(*top_PROOFSEARCH)),
+	   (*top_PROOFSEARCH == (PROOFSEARCH)NULL ? 0 : prfs_KeptClauses(*top_PROOFSEARCH)));
+    printf("\nSPASS allocated %lu KBytes.", memory_DemandedBytes()/1024);
+    fputs("\nSPASS spent\t", stdout);
+    clock_PrintTime(clock_OVERALL);
+    fputs(" on the problem.\n\t\t", stdout);
+    clock_PrintTime(clock_INPUT);
+    fputs(" for the input.\n\t\t", stdout);
+    clock_PrintTime(clock_CNF);
+    fputs(" for the FLOTTER CNF translation.\n\t\t", stdout);
+    clock_PrintTime(clock_INFERENCE);
+    fputs(" for inferences.\n\t\t", stdout);
+    clock_PrintTime(clock_BACKTRACK);
+    fputs(" for the backtracking.\n\t\t", stdout);
+    clock_PrintTime(clock_REDUCTION);
+    puts(" for the reduction.");
+  }
+
+  if (opts_IsSet(top_RemoveFileOptId))
+    remove(top_InputFile);
+
+  exit(EXIT_FAILURE);
+}
+
+#endif
+
+
+/**************************************************************/
+/* Clause Selection Functions                                 */
+/**************************************************************/
+
+static CLAUSE top_SelectClauseDepth(LIST List, FLAGSTORE Flags)
+/**************************************************************
+  INPUT:   A list of clauses and a flag store.
+  RETURNS: A clause selected from the list.
+  EFFECT:  This function selects a clause from the list according
+           to the following criteria:
+	   1. minimal depth
+           2. minimal weight
+	   3a. maximal number of variable occurrences, if the flag
+	       'PrefVar' is TRUE
+	   3b. minimal number of variable occurrences, if 'PrefVar'
+	       is FALSE
+***************************************************************/
+{
+  CLAUSE Result;
+  NAT    Vars,NewVars,Weight,Depth,NewDepth;
+
+  Result = (CLAUSE)list_Car(List);
+  Depth  = clause_Depth(Result);
+  Weight = clause_Weight(Result);
+  Vars   = clause_NumberOfVarOccs(Result);
+  List   = list_Cdr(List);
+
+  while (!list_Empty(List)) {
+    NewDepth =  clause_Depth(list_Car(List));
+    if (NewDepth <= Depth) {
+      if (NewDepth < Depth || clause_Weight(list_Car(List)) < Weight) {
+	Depth  = NewDepth;
+	Result = (CLAUSE)list_Car(List);
+	Weight = clause_Weight(Result);
+	Vars   = clause_NumberOfVarOccs(list_Car(List));
+      }
+      else
+	if (clause_Weight(list_Car(List)) == Weight) {
+	  NewVars = clause_NumberOfVarOccs(list_Car(List));
+	  if (flag_GetFlagValue(Flags, flag_PREFVAR)) {
+	    if (Vars < NewVars) {
+	      Depth  = NewDepth;
+	      Result = (CLAUSE)list_Car(List);
+	      Weight = clause_Weight(Result);
+	      Vars   = NewVars;
+	    }
+	  }
+	  else
+	    if (Vars > NewVars) {
+	      Depth  = NewDepth;
+	      Result = (CLAUSE)list_Car(List);
+	      Weight = clause_Weight(Result);
+	      Vars   = NewVars;
+	    }
+	}
+    }
+    List = list_Cdr(List);
+  }
+
+  return Result;
+}
+
+
+static CLAUSE top_SelectMinimalWeightClause(LIST List, FLAGSTORE Flags)
+/**************************************************************
+  INPUT:   A list of clauses and a flag store.
+  RETURNS: A clause selected from the list.
+  EFFECT:  This function selects a clause with minimal weight.
+           If more than one clause has minimal weight and the flag
+	   'PrefVar' is TRUE, a clause with maximal number of variable
+	   occurrences is selected. If 'PrefVar' is FALSE, a clause with
+	   minimal number of variable occurrences is selected.
+	   If two clauses are equal with respect to the two criteria
+	   the clause with the smaller list position is selected.
+  CAUTION: THE LIST HAS TO BY SORTED BY WEIGHT IN ASCENDING ORDER!
+***************************************************************/
+{
+  CLAUSE Result;
+  NAT    Vars, NewVars, Weight;
+
+#ifdef CHECK
+  /* Check invariant: List has to be sorted by weight (ascending) */
+  LIST Scan;
+  Weight = clause_Weight(list_Car(List));
+  for (Scan = list_Cdr(List); !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+    NAT NewWeight;
+    NewWeight = clause_Weight(list_Car(Scan));
+    if (NewWeight < Weight) {
+      misc_StartErrorReport();
+      misc_ErrorReport("\n In top_SelectMinimalConWeightClause: clause list ");
+      misc_ErrorReport("isn't sorted by weight");
+      misc_FinishErrorReport();
+    }
+    Weight = NewWeight;
+  }
+#endif
+
+  Result = (CLAUSE)list_Car(List);
+  Weight = clause_Weight(Result);
+  Vars   = clause_NumberOfVarOccs(Result);
+  List   = list_Cdr(List);
+
+  while (!list_Empty(List)) {
+    if (clause_Weight(list_Car(List)) == Weight) {
+      NewVars = clause_NumberOfVarOccs(list_Car(List));
+      if (flag_GetFlagValue(Flags, flag_PREFVAR)) {
+	if (Vars < NewVars) {
+	  Result = (CLAUSE)list_Car(List);
+	  Weight = clause_Weight(Result);
+	  Vars   = NewVars;
+	}
+      }
+      else
+	if (Vars > NewVars) {
+	  Result = (CLAUSE)list_Car(List);
+	  Weight = clause_Weight(Result);
+	  Vars   = NewVars;
+	}
+    }
+    else
+      return Result;
+    List = list_Cdr(List);
+  }
+  return Result;
+}
+
+
+static CLAUSE top_SelectMinimalConWeightClause(LIST List, FLAGSTORE Flags)
+/**************************************************************
+  INPUT:   A non-empty list of clauses and a flag store.
+  RETURNS: A clause selected from the list.
+  EFFECT:  This function selects a clause from the list in a
+           similar way as the function top_SelectMinimalWeightClause.
+	   The only difference is that conjecture clauses are
+	   preferred over axiom clauses, because their weight
+	   is divided by a factor given by the flag 'PrefCon'.
+***************************************************************/
+{
+  CLAUSE Result;
+  NAT    NewWeight,Weight, NewVars, Vars, Factor;
+
+  Result = (CLAUSE)list_Car(List);
+  Factor = flag_GetFlagValue(Flags, flag_PREFCON);
+  Weight = clause_Weight(Result);
+  if (clause_GetFlag(Result, CONCLAUSE))
+    Weight = Weight / Factor;
+  Vars   = clause_NumberOfVarOccs(list_Car(List));
+  List   = list_Cdr(List);
+
+  while (!list_Empty(List)) {
+    NewWeight = clause_Weight(list_Car(List));
+    if (clause_GetFlag(list_Car(List),CONCLAUSE))
+      NewWeight = NewWeight / Factor;
+    if (NewWeight < Weight) {
+      Weight = NewWeight;
+      Result = list_Car(List);
+      Vars   = clause_NumberOfVarOccs(list_Car(List));
+    }
+    else {
+      if (NewWeight == Weight) {
+	NewVars = clause_NumberOfVarOccs(list_Car(List));
+	if (flag_GetFlagValue(Flags, flag_PREFVAR)) {
+	  if (Vars < NewVars) {
+	    Result = (CLAUSE)list_Car(List);
+	    Weight = NewWeight;
+	    Vars   = NewVars;
+	  }
+	}
+	else
+	  if (Vars > NewVars) {
+	    Result = (CLAUSE)list_Car(List);
+	    Weight = NewWeight;
+	    Vars   = NewVars;
+	  }
+      }
+    }
+
+    List = list_Cdr(List);
+  }
+  return Result;
+}
+
+
+/*static CLAUSE top_SelectClauseDepth(LIST List)*/
+/**************************************************************
+  INPUT:   A list of clauses.
+  RETURNS: A clause selected from the list.
+  EFFECT:  
+***************************************************************/
+/*{
+  CLAUSE Result;
+  int    Min, Depth;
+
+  Result = (CLAUSE)list_Car(List);
+  Depth  = clause_Depth(Result);
+  Min    = Depth * clause_Weight(Result);
+  List   = list_Cdr(List);
+
+  if (Depth == 0)
+    return Result;
+
+  while (!list_Empty(List)) {
+    Depth =  clause_Depth(list_Car(List));
+    if (Min > Depth * clause_Weight(list_Car(List))) {
+      Result = list_Car(List);
+      if (Depth == 0)
+	return Result;
+      Min    = clause_Depth(Result) * clause_Weight(Result);
+    }
+    List = list_Cdr(List);
+  }
+
+  return Result;
+}*/
+
+
+static LIST top_GetLiteralsForSplitting(CLAUSE Clause)
+/**************************************************************
+  INPUT:   A clause.
+  RETURNS: A list of succedent literal indices where every single
+           literal doesn't share any variables with other literals.
+	   If the clause is horn, an empty list is returned.
+***************************************************************/
+{
+  LIST* Variables;  /* An array, mapping literal index to list of variables */
+  int   i, j;
+  BOOL  Stop;
+  LIST  Failed, Result;
+
+  Result = list_Nil();
+
+  /* Special case: horn clause */
+  if (clause_IsHornClause(Clause))
+    return Result;
+
+  /* Special case: clause is ground, so return all succedent literals */
+  if (clause_IsGround(Clause)) {
+    for (i = clause_LastSuccedentLitIndex(Clause);
+	 i >= clause_FirstSuccedentLitIndex(Clause); i--)
+      Result = list_Cons((POINTER)i, Result);
+    return Result;
+  }
+
+  Variables = memory_Malloc(sizeof(LIST) * clause_Length(Clause));
+  /* Initialize the array */
+  for (i = clause_FirstLitIndex(); i <= clause_LastLitIndex(Clause); i++)
+    Variables[i] = term_VariableSymbols(clause_GetLiteralAtom(Clause, i));
+
+  /* <Failed> is the set of literals that share variables with other literals */
+  Failed = list_Nil();
+  for (i = clause_LastSuccedentLitIndex(Clause);
+       i >= clause_FirstSuccedentLitIndex(Clause); i--) {
+    if (list_Empty(Variables[i]))
+      Result = list_Cons((POINTER)i, Result);
+    else if (!list_PointerMember(Failed, (POINTER)i)) {
+      /* We don't know yet whether the literal shares variables */
+      Stop = FALSE;
+      for (j = clause_FirstLitIndex();
+	   j <= clause_LastLitIndex(Clause) && !Stop; j++) {
+	if (i != j && list_HasIntersection(Variables[i], Variables[j])) {
+	  Stop   = TRUE;  /* Literal isn´t candidate for "optimal" splitting */
+	  Failed = list_Cons((POINTER)i, Failed);
+	  Failed = list_Cons((POINTER)j, Failed);
+	}
+      }
+      if (!Stop)
+	Result = list_Cons((POINTER)i, Result);
+    }
+  }
+  
+  /* Cleanup */
+  for (i = clause_FirstLitIndex(); i <= clause_LastLitIndex(Clause); i++)
+    list_Delete(Variables[i]);
+  memory_Free(Variables, sizeof(LIST) * clause_Length(Clause));
+  list_Delete(Failed);
+  return Result;
+}
+
+
+static int top_GetOptimalSplitLiteralIndex(PROOFSEARCH Search, CLAUSE Clause,
+					   BOOL Usables)
+/**************************************************************
+  INPUT:   A proofsearch object, a clause and a boolean flag.
+  RETURNS: The index of the positive literal from <Clause>
+           with the greatest number of instances (maybe 0) within
+	   the WorkedOff/Usable sets of the proof search object.
+	   The literal mustn't share any variables with other literals.
+	   If the clause doesn't have a suitable literal, a negative
+	   number is returned.
+  EFFECT:  If <Usables> is FALSE, only the number of instances
+	   within the WorkedOff set is considered, otherwise
+	   the number of instances within both clause sets is considered.
+***************************************************************/
+{
+  LIST    SplitLits;
+  LITERAL Literal;
+  NAT     Count, MaxInstances;
+  int     Result;
+
+  MaxInstances = -1;
+  SplitLits    = top_GetLiteralsForSplitting(Clause);
+  Result       = -1;
+
+  for ( ; !list_Empty(SplitLits); SplitLits = list_Pop(SplitLits)) {
+    Literal = clause_GetLiteral(Clause, (int)list_Car(SplitLits));
+    /* Count the number of instances */
+    Count = prfs_GetNumberOfInstances(Search, Literal, Usables);
+    if (Count > MaxInstances) {
+      Result = (int)list_Car(SplitLits);
+      MaxInstances = Count;
+    }
+  }
+  return Result;
+}
+
+
+/* EK: hier lassen oder nach search.c oder nach rules-split.c? */
+static CLAUSE top_GetPowerfulSplitClause(PROOFSEARCH Search, BOOL Usables,
+					 int* LitIndex)
+/**************************************************************
+  INPUT:   A proofsearch object, a boolean flag and a pointer to a literal
+           index which is used as return value.
+  RETURNS: A clause from the usable set that was selected as given clause.
+           Iff no suitable clause was found NULL is returned and <*LitIndex>
+	   is set to -1.
+	   Iff a suitable clause was found, this clause is returned and
+	   <*LitIndex> is set to the index of the "optimal" literal.
+  EFFECT:  This function selects a clause from the "usable" set and
+           a literal that are "optimal" for the application of the splitting
+	   rule with respect to the following criteria:
+           1) the literal must occur in the succedent of the non-horn clause,
+	   2) the literal mustn't share any variables with other literals,
+           3) the clause must have a solved constraint,
+	   4) the atom must have the maximum number of instances
+              a) within the set of "workedoff" clauses, iff <Usables>=FALSE
+              b) within the set of "usable" and "workedoff" clauses,
+                 iff "Usables"=TRUE
+	   5) the atom must have at least one instance in another clause.
+***************************************************************/
+{
+  LIST   Scan, SplitLits;
+  NAT    MaxNrOfInstances, NrOfInstances;
+  CLAUSE Clause, OptimalClause;
+  TERM   Atom;
+  SHARED_INDEX WOIndex, UsIndex;
+
+  OptimalClause    = NULL;
+  *LitIndex        = -1;
+  MaxNrOfInstances = 0;
+  WOIndex          = prfs_WorkedOffSharingIndex(Search);
+  UsIndex          = prfs_UsableSharingIndex(Search);
+
+  /* Prepare the term stamp */
+  if (term_StampOverflow(sharing_StampID(WOIndex)))
+    sharing_ResetAllTermStamps(WOIndex);
+  if (Usables && term_StampOverflow(sharing_StampID(UsIndex)))
+    sharing_ResetAllTermStamps(UsIndex);
+  term_StartStamp();
+
+  for (Scan = prfs_UsableClauses(Search); !list_Empty(Scan);
+       Scan = list_Cdr(Scan)) {
+    Clause = list_Car(Scan);
+    if (clause_HasSolvedConstraint(Clause) && !clause_IsHornClause(Clause)) {
+      /* Get a list of splittable literal indices */
+      SplitLits = top_GetLiteralsForSplitting(Clause);
+      for ( ; !list_Empty(SplitLits); SplitLits = list_Pop(SplitLits)) {
+	LITERAL Literal;
+
+	Literal = clause_GetLiteral(Clause, (int)list_Car(SplitLits));
+	Atom    = clause_LiteralAtom(Literal);
+ 	if (!term_AlreadyVisited(Atom)) {
+	  /* Don't visit atom more than once */
+ 	  term_SetTermStamp(Atom);
+	  /* Count the number of instances */
+	  NrOfInstances = prfs_GetNumberOfInstances(Search, Literal, Usables);
+	  if (NrOfInstances > MaxNrOfInstances || OptimalClause == NULL ||
+	      (NrOfInstances == MaxNrOfInstances &&
+	       /* Prefer shorter clauses for splitting! */
+	       clause_Length(Clause) < clause_Length(OptimalClause))) {
+	    OptimalClause    = Clause;
+	    MaxNrOfInstances = NrOfInstances;
+	    *LitIndex        = (int)list_Car(SplitLits);
+	  }
+ 	}
+      }
+    }
+  }
+  term_StopStamp();
+
+  /* The splittable literal must have at least one instance to be useful */
+  /* reducing other clauses. If <Usables> is TRUE, the literal must even */
+  /* have two instances, since the literal of the given clause is in the */
+  /* usable index, too.                                                  */
+  if (MaxNrOfInstances == 0 || (Usables && MaxNrOfInstances == 1)) {
+    *LitIndex     = -1;
+    OptimalClause = NULL;
+  }
+
+  return OptimalClause;
+}
+
+
+static LIST top_FullReductionSelectGivenComputeDerivables(PROOFSEARCH Search,
+							  CLAUSE *SplitClause,
+							  int *Counter)
+/**************************************************************
+  INPUT:   A proof search object, a pointer to a clause resulting from a
+           previous splitting step, and a pointer to an integer counter.
+  RETURNS: A list of derived clauses.
+  EFFECT:  In this function a clause is selected from the set of
+           "usable" clauses. After a clause was selected as "given clause",
+	   inferences between the given clause and the "worked off" clauses
+	   are made. The selection works as follows:
+	   1) If <*SplitClause> is not NULL, the split clause
+	      is selected as "given clause". <*SplitClause> should result
+	      from splitting
+	   2) If <*SplitClause> is NULL, we try to find a clause that is
+	      "optimal" for splitting. This is done by selecting a literal
+	      <L> in a clause, such that <L> is variable-disjoint from
+	      the rest of the clause, and the atom of <L> has the maximum
+	      number of instances within the set of "usable" and "workoff"
+	      clauses.
+	   3) If the previous steps failed, a clause is selected by weight
+	      or by depth, depending on the parameters "WDRatio", "PrefVar"
+	      and "PrefCon". Then splitting is tried on the selected clause.
+	      If the clause is a non-horn clause, we try to find a positive
+	      literal <L> and a set of negative literals <N>, such that <N>
+	      and <L> are variable disjoint from the rest of the clause.
+***************************************************************/
+{
+  CLAUSE     GivenClause, TerminatorClause;
+  LIST       Derivables, SplitLits;
+  FLAGSTORE  Flags;
+  PRECEDENCE Precedence;
+  int        LitIndex;
+
+  GivenClause = NULL;
+  Derivables  = list_Nil();
+  Flags       = prfs_Store(Search);
+  Precedence  = prfs_Precedence(Search);
+
+  /* 1) If the last given clause was split or if backtracking was applied, */
+  /* then choose the clause resulting from the splitting step as        */
+  /* given clause.                                                      */
+  /* ATTENTION: Since the <SplitClause> might have been reduced since   */
+  /* the time the variable was set, we have to check whether            */
+  /* <SplitClause> is still element of the set of usable clauses.       */
+  if (*SplitClause != NULL &&
+      list_PointerMember(prfs_UsableClauses(Search), *SplitClause))
+    GivenClause = *SplitClause;
+  
+  *SplitClause = NULL;
+
+  if (GivenClause == NULL) {
+    if (prfs_SplitCounter(Search) != 0)
+      /* 2) Try to find an "optimal" splitting clause, that doesn't share */
+      /*    variables with any other literal.                             */
+      GivenClause = top_GetPowerfulSplitClause(Search, FALSE, &LitIndex);
+      
+    if (GivenClause != NULL) {
+      /* Found "optimal" split clause, so apply splitting */
+      SplitLits = list_List(clause_GetLiteral(GivenClause, LitIndex));
+      *SplitClause = prfs_DoSplitting(Search, GivenClause, SplitLits);
+      list_Delete(SplitLits);      
+    } else {
+      /* 3) Splitting wasn't applied, so use the other strategies */
+      if ((*Counter) % flag_GetFlagValue(Flags, flag_WDRATIO) == 0)
+	GivenClause = top_SelectClauseDepth(prfs_UsableClauses(Search), Flags);
+      else {
+	if (flag_GetFlagValue(Flags, flag_PREFCON) != flag_PREFCONUNCHANGED)
+	  GivenClause = top_SelectMinimalConWeightClause(prfs_UsableClauses(Search),
+							 Flags);
+	else
+	  GivenClause = top_SelectMinimalWeightClause(prfs_UsableClauses(Search),
+						      Flags);
+      }
+      (*Counter)++; /* EK: hier lassen, oder eine Klammerebene nach aussen? */
+    }
+  }
+
+  if (*SplitClause == NULL && prfs_SplitCounter(Search) != 0) {
+    /* Try to find the "optimal" literal for splitting the clause. */
+    /* This makes sense for a clause that is the right part of a   */
+    /* splitting step.                                             */
+    LitIndex = top_GetOptimalSplitLiteralIndex(Search, GivenClause, FALSE);
+    if (LitIndex >= 0) {
+      SplitLits = list_List(clause_GetLiteral(GivenClause, LitIndex));
+      *SplitClause = prfs_DoSplitting(Search, GivenClause, SplitLits);
+      list_Delete(SplitLits);
+    } else {
+      /* Optimal splitting wasn't possible, so try the old-style splitting. */
+      /* Here a split is done if a positive literal doesn't share variables */
+      /* with another POSITIVE literal. */
+      *SplitClause = prfs_PerformSplitting(Search, GivenClause);
+    }
+  }
+
+  prfs_ExtractUsable(Search, GivenClause);
+
+  if (flag_GetFlagValue(Flags, flag_PGIVEN)) {
+    fputs("\n\tGiven clause: ", stdout);
+    clause_Print(GivenClause);
+    fflush(stdout);
+  }
+  
+  if (*SplitClause != NULL)
+    Derivables = list_List(*SplitClause);
+  else {
+    /* No splitting was applied */
+    if (flag_GetFlagValue(Flags, flag_RTER) != flag_RTEROFF) {
+      clock_StartCounter(clock_REDUCTION);
+      TerminatorClause = red_Terminator(GivenClause,
+					flag_GetFlagValue(Flags, flag_RTER),
+					prfs_WorkedOffSharingIndex(Search),
+					prfs_UsableSharingIndex(Search), Flags,
+					Precedence);
+      clock_StopAddPassedTime(clock_REDUCTION);
+      
+      if (TerminatorClause != NULL) {
+	/* An empty clause was derived by the "terminator" rule */
+	Derivables = list_List(TerminatorClause);
+	prfs_InsertUsableClause(Search, GivenClause);
+      }
+    }
+    if (list_Empty(Derivables)) {
+      /* No splitting was applied, no empty clause was found by terminator */
+      clause_SelectLiteral(GivenClause, Flags);
+      /*clause_SetSpecialFlags(GivenClause,ana_SortDecreasing());*/
+      prfs_InsertWorkedOffClause(Search, GivenClause);
+      clock_StartCounter(clock_INFERENCE);
+      Derivables = inf_DerivableClauses(Search, GivenClause);
+      clock_StopAddPassedTime(clock_INFERENCE);
+    }
+  }
+
+  prfs_IncDerivedClauses(Search, list_Length(Derivables));
+
+  return Derivables;
+}
+
+
+static LIST top_LazyReductionSelectGivenComputeDerivables(PROOFSEARCH Search,
+							  CLAUSE *SplitClause,
+							  int *Counter)
+/**************************************************************
+  INPUT:   A proof search object, a pointer to a clause resulting from a
+           previous splitting step, and a pointer to an integer counter.
+  RETURNS: A list of derived clauses.
+  EFFECT:  In this function a clause is selected from the set of
+           "usable" clauses. After a clause was selected as "given clause",
+	   inferences between the given clause and the "worked off" clauses
+	   are made. Take a look at the description of the function
+	   top_FullReduction... for more details.
+	   This function is more complicated than the other function,
+	   since clauses in the set of usable clauses may be reducible.
+	   Because of this fact, the selection of the given clause
+	   has to be done in a loop. After picking a "candidate" clause
+	   the clause is inter-reduced with the "worked off" set.
+	   If the candidate still exists after the reduction it is
+	   selected as given clause, else another usable clause is picked
+	   as candidate.
+***************************************************************/
+{
+  CLAUSE     GivenClause, TerminatorClause;
+  LIST       Derivables;
+  FLAGSTORE  Flags;
+  PRECEDENCE Precedence;
+  int        LitIndex;
+
+  GivenClause      = (CLAUSE)NULL;
+  TerminatorClause = (CLAUSE)NULL;
+  Derivables       = list_Nil();
+  Flags            = prfs_Store(Search);
+  Precedence       = prfs_Precedence(Search);
+
+  while (GivenClause == (CLAUSE)NULL &&
+	 !list_Empty(prfs_UsableClauses(Search))) {
+    /* The selected clause may be redundant */
+
+    if (*SplitClause != NULL &&
+	list_PointerMember(prfs_UsableClauses(Search), *SplitClause))
+      GivenClause = *SplitClause;
+
+    *SplitClause  = NULL;
+
+    /* Try selecting a clause that is optimal for splitting */
+    if (GivenClause == NULL) {
+      if (prfs_SplitCounter(Search) != 0) {
+	GivenClause = top_GetPowerfulSplitClause(Search, FALSE, &LitIndex);
+	/* The value of <LitIndex> isn't used here. */
+      }
+
+      if (GivenClause == NULL) {
+	/* No optimal clause for splitting found */
+	if ((*Counter) % flag_GetFlagValue(Flags, flag_WDRATIO) == 0)
+	  GivenClause = top_SelectClauseDepth(prfs_UsableClauses(Search), Flags);
+	else {
+	  if (flag_GetFlagValue(Flags, flag_PREFCON) != flag_PREFCONUNCHANGED)
+	    GivenClause = top_SelectMinimalConWeightClause(prfs_UsableClauses(Search),
+							   Flags);
+	  else
+	    GivenClause = top_SelectMinimalWeightClause(prfs_UsableClauses(Search),
+							Flags);
+	}
+	(*Counter)++;
+      }
+    }
+    prfs_ExtractUsable(Search, GivenClause);
+
+    /* Reduce the selected clause */
+    clock_StartCounter(clock_REDUCTION);
+    GivenClause = red_CompleteReductionOnDerivedClause(Search, GivenClause, 
+						       red_WORKEDOFF);
+    clock_StopAddPassedTime(clock_REDUCTION);
+  }
+
+  if (GivenClause == (CLAUSE)NULL)
+    /* Set of usable clauses is empty */
+    return list_Nil();
+
+  
+  if (clause_IsEmptyClause(GivenClause)) {
+    Derivables = list_List(GivenClause);
+    return Derivables;
+  }
+  else {
+    /* Reduce Workedoff clauses with selected clause */
+    clock_StartCounter(clock_REDUCTION);
+    Derivables = red_BackReduction(Search, GivenClause, red_WORKEDOFF);
+    clock_StopAddPassedTime(clock_REDUCTION);
+  }
+
+  /* Print selected clause */
+  if (flag_GetFlagValue(Flags, flag_PGIVEN)) {
+    fputs("\n\tGiven clause: ", stdout);
+    clause_Print(GivenClause); 
+    fflush(stdout);
+  }     
+
+  /* Try splitting */
+  if (prfs_SplitCounter(Search) != 0) {
+    /* First try "optimal" splitting on the selected clause */
+    LitIndex = top_GetOptimalSplitLiteralIndex(Search, GivenClause, FALSE);
+
+    if (LitIndex >= 0) {
+      LIST SplitLits;
+
+      SplitLits = list_List(clause_GetLiteral(GivenClause, LitIndex));
+      *SplitClause = prfs_DoSplitting(Search, GivenClause, SplitLits);
+      list_Delete(SplitLits);      
+    } else {
+      /* Try the old splitting that allows negative literals   */
+      /* sharing variables with the selected positive literal. */
+      *SplitClause = prfs_PerformSplitting(Search, GivenClause);
+    }
+  } 
+  
+  if (*SplitClause != NULL) {
+    Derivables = list_Cons(*SplitClause, Derivables);
+  } else {
+    /* Try terminator reduction only for a clause that wasn't splitted. */
+    if (flag_GetFlagValue(Flags, flag_RTER) != flag_RTEROFF) {
+      TerminatorClause = red_Terminator(GivenClause,
+					flag_GetFlagValue(Flags, flag_RTER),
+					prfs_WorkedOffSharingIndex(Search),
+					prfs_UsableSharingIndex(Search),
+					Flags, Precedence);
+      if (TerminatorClause != NULL) {
+	Derivables = list_Cons(TerminatorClause, Derivables);
+	prfs_InsertUsableClause(Search, GivenClause);
+      }
+    }
+    if (TerminatorClause == (CLAUSE)NULL) {   
+      clause_SelectLiteral(GivenClause, Flags);
+      /* clause_SetSpecialFlags(GivenClause,ana_SortDecreasing());*/
+      prfs_InsertWorkedOffClause(Search, GivenClause);
+      clock_StartCounter(clock_INFERENCE);
+      Derivables = list_Nconc(Derivables,
+			      inf_DerivableClauses(Search, GivenClause));
+      clock_StopAddPassedTime(clock_INFERENCE);
+    }
+  }
+  
+  prfs_IncDerivedClauses(Search, list_Length(Derivables));
+
+  return Derivables;
+}
+
+
+static PROOFSEARCH top_ProofSearch(PROOFSEARCH Search, LIST ProblemClauses,
+				   FLAGSTORE InputFlags, LIST UserPrecedence, int *BoundApplied)
+/**************************************************************
+  INPUT:   A proof search object, a list of clauses, a flag store
+           containing the flags from the command line and from
+           the input file, a list containing the precedence as
+	   specified by the user, and a pointer to an integer.
+  RETURNS: The same proof search object
+  EFFECTS: 
+***************************************************************/
+{
+  LIST       Scan,EmptyClauses,Derivables;
+  LIST       UsedEmptyClauses;
+  CLAUSE     SplitClause,HighestLevelEmptyClause;
+  FLAGSTORE  Flags;
+  PRECEDENCE Precedence;
+  int        Counter, ActBound, BoundMode, BoundLoops;
+
+  HighestLevelEmptyClause = (CLAUSE)NULL;
+  UsedEmptyClauses        = list_Nil();
+  EmptyClauses            = list_Nil();
+  Derivables              = list_Nil();
+  Flags                   = prfs_Store(Search);
+  Precedence              = prfs_Precedence(Search);
+  Counter                 = 1;
+
+  clock_InitCounter(clock_REDUCTION);
+  clock_InitCounter(clock_BACKTRACK);
+  clock_InitCounter(clock_INFERENCE);
+
+  /* Important ! Recomputes Weight ! */
+  ana_AnalyzeProblem(Search, ProblemClauses);
+  if (flag_GetFlagValue(Flags, flag_AUTO)) {
+    prfs_InstallFiniteMonadicPredicates(Search, ProblemClauses, ana_FinMonPredList());
+    ana_AutoConfiguration(ProblemClauses, Flags, Precedence);
+    /* File and input flags have higher precedence */
+    flag_TransferSetFlags(InputFlags, Flags);
+  }
+
+  /* Rearrange automatically determined precedence according to user's specification. */
+  symbol_RearrangePrecedence(Precedence, UserPrecedence);
+
+  for (Scan = ProblemClauses; !list_Empty(Scan); Scan = list_Cdr(Scan))
+    clause_OrientAndReInit(list_Car(Scan), Flags, Precedence);
+
+  /* Must be called after ana_AnalyzeProblem and Reorientation */
+  ana_AnalyzeSortStructure(ProblemClauses, Flags, Precedence);
+
+  if (flag_GetFlagValue(Flags, flag_AUTO)) {
+    ana_ExploitSortAnalysis(Flags);
+    /* File and input flags have higher precedence */
+    flag_TransferSetFlags(InputFlags, Flags);
+  }
+  prfs_SetSplitCounter(Search, flag_GetFlagValue(Flags, flag_SPLITS));
+
+  ActBound       = flag_GetFlagValue(Flags, flag_BOUNDSTART);
+  BoundMode      = flag_GetFlagValue(Flags, flag_BOUNDMODE);
+  BoundLoops     = flag_GetFlagValue(Flags, flag_BOUNDLOOPS);
+  *BoundApplied  = -1;
+
+  if (flag_GetFlagValue(Flags, flag_PPROBLEM)) {
+    puts("");
+    puts("--------------------------SPASS-START-----------------------------");
+    puts("Input Problem:");
+    clause_ListPrint(ProblemClauses);
+    ana_Print(Flags, Precedence);
+  }
+
+  if (flag_GetFlagValue(Flags, flag_SORTS) != flag_SORTSOFF) {
+    BOOL Strong;
+    Strong = (flag_GetFlagValue(Flags, flag_SORTS) == flag_SORTSMONADICALL);
+    for (Scan = ProblemClauses; !list_Empty(Scan); Scan = list_Cdr(Scan))
+      clause_SetSortConstraint((CLAUSE)list_Car(Scan),Strong,Flags, Precedence);
+  }
+
+  if (flag_GetFlagValue(Flags, flag_RINPUT)) {
+    clock_StartCounter(clock_REDUCTION);
+    EmptyClauses = red_ReduceInput(Search, ProblemClauses);
+    clock_StopAddPassedTime(clock_REDUCTION);
+    if (list_Empty(EmptyClauses) && flag_GetFlagValue(Flags, flag_SATINPUT))
+      EmptyClauses = red_SatInput(Search);
+  }
+  else {
+    for (Scan=ProblemClauses; !list_Empty(Scan); Scan=list_Cdr(Scan))
+      prfs_InsertUsableClause(Search, list_Car(Scan));
+  }
+  Derivables = list_Nil();
+
+  if (ana_SortRestrictions() ||
+      (ana_UnsolvedSortRestrictions() &&
+       flag_GetFlagValue(Flags,flag_SORTS) == flag_SORTSMONADICALL)) {
+    if (flag_GetFlagValue(Flags, flag_RSST))
+      prfs_SetStaticSortTheory(Search,sort_ApproxStaticSortTheory(prfs_UsableClauses(Search),Flags,Precedence));
+    prfs_SetDynamicSortTheory(Search,sort_TheoryCreate());
+  }
+
+  /* Fix literal order in clauses in the usable set.
+     Since they are shared, we have to extract them from
+     the sharing before fixing them. Afterwards, we have to
+     insert them in the sharing again.
+  */ 
+  for (Scan = prfs_UsableClauses(Search);
+       !list_Empty(Scan);
+       Scan = list_Cdr(Scan)) {
+    CLAUSE clause;
+    clause = list_Car(Scan);
+    clause_MakeUnshared(clause,prfs_UsableSharingIndex(Search));
+    clause_FixLiteralOrder(clause, Flags, Precedence);
+    clause_InsertIntoSharing(clause, prfs_UsableSharingIndex(Search),
+			     prfs_Store(Search), prfs_Precedence(Search));
+  }
+
+  /* Calculate the frequency counts for the symbols in the usable set. */
+  for (Scan = prfs_UsableClauses(Search);
+       !list_Empty(Scan);
+       Scan = list_Cdr(Scan)) {
+    CLAUSE clause;
+    clause = list_Car(Scan);
+
+    clause_CountSymbols(clause);
+  }
+
+  /* Sort usable set. */
+  prfs_SetUsableClauses(Search, 
+			list_Sort(prfs_UsableClauses(Search), 
+				  (BOOL (*) (void *, void *)) clause_CompareAbstractLEQ));
+
+  if (flag_GetFlagValue(Flags, flag_SOS)) {
+    Derivables = list_Copy(prfs_UsableClauses(Search));
+    for (Scan=Derivables;!list_Empty(Scan);Scan=list_Cdr(Scan))
+      if (!clause_GetFlag(list_Car(Scan), CONCLAUSE))
+	prfs_MoveUsableWorkedOff(Search,list_Car(Scan));
+    list_Delete(Derivables);
+  }
+
+  if (flag_GetFlagValue(Flags, flag_PPROBLEM)) {
+    puts("\nProcessed Problem:");
+    puts("\nWorked Off Clauses:");
+    clause_ListPrint(prfs_WorkedOffClauses(Search));
+    puts("\nUsable Clauses:");
+    clause_ListPrint(prfs_UsableClauses(Search));
+  }
+
+  while ((list_Empty(EmptyClauses) || !prfs_SplitStackEmpty(Search)) && 
+	 prfs_Loops(Search) != 0 &&
+	 ((*BoundApplied != -1) || !list_Empty(prfs_UsableClauses(Search))) &&
+	 (flag_GetFlagValue(Flags,flag_TIMELIMIT) == flag_TIMELIMITUNLIMITED ||
+	  flag_GetFlagValue(Flags,flag_TIMELIMIT) > clock_GetSeconds(clock_OVERALL))) {
+
+    Derivables    = list_Nil();
+    SplitClause   = (CLAUSE)NULL;
+    *BoundApplied = -1;
+
+    while ((list_Empty(EmptyClauses) || !prfs_SplitStackEmpty(Search)) && 
+	   prfs_Loops(Search) != 0 &&
+	   (!list_Empty(prfs_UsableClauses(Search)) || !list_Empty(EmptyClauses)) &&
+	   (flag_GetFlagValue(Flags,flag_TIMELIMIT) == flag_TIMELIMITUNLIMITED ||
+	    flag_GetFlagValue(Flags,flag_TIMELIMIT) > clock_GetSeconds(clock_OVERALL))) {
+      
+      if (!list_Empty(EmptyClauses)) {
+	/* Backtracking */
+	clock_StartCounter(clock_BACKTRACK);
+	Derivables = split_Backtrack(Search, HighestLevelEmptyClause,
+				     &SplitClause);
+	clock_StopAddPassedTime(clock_BACKTRACK);
+	prfs_IncBacktrackedClauses(Search, list_Length(Derivables));
+      
+	if (prfs_SplitStackEmpty(Search))
+	  Derivables = list_Nconc(EmptyClauses, Derivables);
+	else {
+	  for ( ; !list_Empty(EmptyClauses); EmptyClauses = list_Pop(EmptyClauses))
+	    if (list_Car(EmptyClauses) != HighestLevelEmptyClause)
+	      clause_Delete(list_Car(EmptyClauses));
+	  prfs_InsertDocProofClause(Search, HighestLevelEmptyClause);
+	  /* Keep HighestLevelEmptyClause for finding the terms required */
+	  /* for the proof.                                              */
+	  if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+	    UsedEmptyClauses = list_Cons(HighestLevelEmptyClause, UsedEmptyClauses);
+	  if (flag_GetFlagValue(Flags, flag_DOCSPLIT))
+	    printf("\n\t Split Backtracking level %d:",prfs_ValidLevel(Search));
+	}
+	EmptyClauses            = list_Nil();
+	HighestLevelEmptyClause = (CLAUSE)NULL;
+      }
+      else {   /* no empty clause found */
+
+#ifdef CHECK
+	if (!prfs_Check(Search)) {
+	  misc_StartErrorReport();
+	  misc_ErrorReport("\n In top_ProofSearch: Illegal state of search in SPASS.\n");
+	  misc_FinishErrorReport();
+	}
+	if (!ana_Equations())
+	  red_CheckSplitSubsumptionCondition(Search);
+#endif 
+
+	if (flag_GetFlagValue(Flags, flag_FULLRED))
+	  Derivables = top_FullReductionSelectGivenComputeDerivables(Search, &SplitClause, &Counter);
+	else
+	  Derivables = top_LazyReductionSelectGivenComputeDerivables(Search, &SplitClause, &Counter);
+      }
+
+      /* Print the derived clauses, if required */
+      if (flag_GetFlagValue(Flags, flag_PDER))
+	for (Scan=Derivables; !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+	  fputs("\nDerived: ", stdout); 
+	  clause_Print(list_Car(Scan));
+	}
+
+      /* Partition the derived clauses into empty and non-empty clauses */
+      Derivables = split_ExtractEmptyClauses(Derivables, &EmptyClauses);
+
+      /* Apply reduction rules */
+      clock_StartCounter(clock_REDUCTION);
+      if (flag_GetFlagValue(Flags, flag_FULLRED)) {
+	EmptyClauses = 
+	  list_Nconc(EmptyClauses,
+		     red_CompleteReductionOnDerivedClauses(Search, Derivables,
+							   red_ALL, ActBound,
+							   BoundMode,
+							   BoundApplied));
+      } else {
+	EmptyClauses =
+	  list_Nconc(EmptyClauses,
+		     red_CompleteReductionOnDerivedClauses(Search, Derivables,
+							   red_WORKEDOFF,
+							   ActBound, BoundMode,
+							   BoundApplied));
+      }
+      clock_StopAddPassedTime(clock_REDUCTION);
+      
+
+      if (!list_Empty(EmptyClauses)) {
+	HighestLevelEmptyClause = split_SmallestSplitLevelClause(EmptyClauses);
+	if (flag_GetFlagValue(Flags, flag_PEMPTYCLAUSE)) {
+	  fputs("\nEmptyClause: ", stdout);
+	  clause_Print(HighestLevelEmptyClause);
+	}
+      }
+      prfs_DecLoops(Search);
+    }
+  
+    if (ActBound != flag_BOUNDSTARTUNLIMITED &&
+	BoundMode != flag_BOUNDMODEUNLIMITED) {
+      BoundLoops--;
+      if (BoundLoops == flag_BOUNDLOOPSMIN)
+	ActBound = flag_BOUNDSTARTUNLIMITED;
+      else
+	ActBound = *BoundApplied;
+      if (*BoundApplied != -1) {
+	prfs_SwapIndexes(Search);
+	if  (flag_GetFlagValue(Flags,flag_PBINC))
+	  printf("\n\n\t ---- New Clause %s Bound: %2d ----\n",
+		 (BoundMode==flag_BOUNDMODERESTRICTEDBYDEPTH) ? "Term Depth" : "Weight",ActBound);
+      }
+    }
+  }
+  prfs_SetEmptyClauses(Search, EmptyClauses);
+  prfs_SetUsedEmptyClauses(Search, UsedEmptyClauses);
+
+  return Search;
+}
+
+
+static void top_Flotter(int argc, const char* argv[], LIST InputClauses)
+/**************************************************************
+  INPUT:  
+  RETURNS: Nothing.
+  EFFECT:  
+***************************************************************/
+{
+  FILE *Output;
+  char *description;
+  const char *creator = "\n\tCNF generated by FLOTTER " misc_VERSION " *}";
+  int  size;
+  int  creator_size;
+
+  if (argc < opts_Indicator()+2)
+    Output = stdout;
+  else
+    Output = misc_OpenFile(argv[opts_Indicator()+1],"w");
+
+  creator_size = (int)strlen(creator);
+  size        = (int)strlen(dfg_ProblemDescription()) + creator_size;
+  description = (char*)memory_Malloc(sizeof(char)*size);
+  strncpy(description,dfg_ProblemDescription(),size-creator_size-3);
+  strcpy(description+size-creator_size-3, creator);
+
+  
+  clause_FPrintCnfDFGProblem(Output, dfg_ProblemName(), dfg_ProblemAuthor(), 
+			     dfg_ProblemStatusString(), description, InputClauses);
+  
+  fputs("\nFLOTTER needed\t", stdout);
+  clock_PrintTime(clock_INPUT);
+  puts(" for the input.");
+  fputs("\t\t", stdout);
+  clock_PrintTime(clock_CNF);
+  fputs(" for the  CNF translation.", stdout);
+  
+
+  if (Output != stdout)
+    misc_CloseFile(Output,argv[opts_Indicator()+1]);
+  memory_Free(description, sizeof(char)*size);
+}
+
+static BOOL top_CalledFlotter(const char* Call)
+{
+  int length;
+  length = strlen(Call);
+  return string_Equal((Call + (length > 7 ? length - 7 : 0)), "FLOTTER");
+}
+
+
+
+/**************************************************************/
+/* Main Function                                              */
+/**************************************************************/
+
+int main(int argc, const char* argv[])
+{
+  LIST              InputClauses,Scan,Axioms,Conjectures, Sorts, QueryClauses, 
+    LabelClauses, QueryPair, ProblemClauses, Labellist, Sortlabellist, 
+    Symblist, UserPrecedence;
+  PROOFSEARCH       Search, FlotterSearch;
+  /* <InputFlags> are the flags from the problem file and the command line. */
+  FLAGSTORE         InputFlags, Flags;
+  /* <InputPrecedence> is the precedence after reading the problem file. */
+  PRECEDENCE        InputPrecedence, Precedence;
+  FILE*             InputStream; 
+  HASH              TermLabelToClauselist, ClauseToTermLabellist;
+  top_SEARCHRESULT  Result;
+
+  Search = (PROOFSEARCH)NULL;
+  
+#if (defined(SPASS_SIGNALS))
+  top_PROOFSEARCH = &Search;
+  signal(SIGINT, top_SigHandler);
+  signal(SIGTERM, top_SigHandler);
+  signal(SIGSEGV, top_SigHandler);
+  signal(SIGBUS, top_SigHandler);
+#endif
+
+  clock_Init();
+  clock_StartCounter(clock_OVERALL);
+  memory_Init(memory__UNLIMITED);
+  atexit(memory_FreeAllMem);
+  symbol_Init(TRUE);
+  stack_Init();
+  hash_Init();
+  sort_Init();
+  term_Init();
+
+  InputPrecedence = symbol_CreatePrecedence();
+  fol_Init(TRUE, InputPrecedence);
+  cont_Init();
+  unify_Init();
+  flag_Init();
+  subs_Init();
+  clause_Init();
+  red_Init();
+  ren_Init();
+  dp_Init();
+  opts_Init();
+  ana_Init();
+  cc_Init();
+
+  /* Build proof search object to store definitions in */
+  Search      = prfs_Create();
+  InputFlags  = flag_CreateStore();
+
+  /* declare all options */
+  opts_DeclareSPASSFlagsAsOptions();
+  top_RemoveFileOptId = opts_Declare("rf", opts_NOARGTYPE);
+
+  if (!opts_Read(argc, argv)) 
+    return EXIT_FAILURE;
+
+   /* Check whether flag_STDIN is set in the command line */
+  flag_InitStoreByDefaults(InputFlags);
+  opts_SetFlags(InputFlags);
+
+  if (argc < opts_Indicator()+1 && !flag_GetFlagValue(InputFlags,flag_STDIN)) {
+    /* No input file, no stdin input */
+    printf("\n\t          %s %s",argv[0],misc_VERSION);
+    if (top_CalledFlotter(argv[0]) ||
+	flag_GetFlagValue(InputFlags, flag_FLOTTER))
+      puts("\n\t       Usage: FLOTTER [options] [<input-file>] [<output-file>]\n");
+    else
+      puts("\n\t       Usage: SPASS [options] [<input-file>] \n");
+    puts("Possible options:\n");
+    opts_PrintSPASSNames(); 
+    return EXIT_FAILURE;
+  }
+  FlotterSearch = NULL;
+
+  Axioms = Conjectures = Sorts = Labellist = Sortlabellist = UserPrecedence = list_Nil();
+  
+  if (flag_GetFlagValue(InputFlags, flag_STDIN)) {
+    top_InputFile = (char*)NULL;
+    InputStream   = stdin;
+  } else {
+    top_InputFile = argv[opts_Indicator()];
+    InputStream = misc_OpenFile(top_InputFile, "r");
+  }
+  
+  clock_StartCounter(clock_INPUT);
+  flag_CleanStore(InputFlags);  /* Mark all flags as unset */
+
+  /* Now add flags from file to InputFlags and set precedence */
+  InputClauses = dfg_DFGParser(InputStream, InputFlags, InputPrecedence, &Axioms,
+			       &Conjectures, &Sorts, &UserPrecedence); 
+
+  /* Add/overwrite with command line flags */
+  opts_SetFlags(InputFlags);
+  Flags      = prfs_Store(Search);
+  Precedence = prfs_Precedence(Search);
+  /* The Flags were initialized with the default flag values.  */
+  /* This values are now overwritten by command line flags and flags */
+  /* from the input file. */
+  flag_TransferSetFlags(InputFlags, Flags);
+  /* From now on the input flags are not changed! */
+
+  /* Transfer input precedence to search object */
+  symbol_TransferPrecedence(InputPrecedence, Precedence);
+
+
+  /* Complain about missing input clauses/formulae when in */
+  /* non-interactive mode */
+  if (!flag_GetFlagValue(Flags, flag_INTERACTIVE) && list_Empty(Axioms) &&
+      list_Empty(Conjectures) && list_Empty(InputClauses)) {
+    misc_StartUserErrorReport();
+    misc_UserErrorReport("\n No formulae and clauses found in input file!\n");
+    misc_FinishUserErrorReport();
+  }
+
+  cnf_Init(Flags);  /* Depends on Strong Skolemization Flag */
+
+  /* DocProof is required for interactive mode */
+  if (flag_GetFlagValue(Flags, flag_INTERACTIVE)) {
+    flag_SetFlagValue(Flags, flag_DOCPROOF, flag_DOCPROOFON);
+  }
+
+  if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+    prfs_AddDocProofSharingIndex(Search);
+
+  /* Create necessary hasharrays */
+  if (flag_GetFlagValue(Flags, flag_DOCPROOF)) {
+    TermLabelToClauselist = hsh_Create();
+    ClauseToTermLabellist = hsh_Create();
+  }
+  else {
+    TermLabelToClauselist = NULL;
+    ClauseToTermLabellist = NULL;
+  }
+  
+  /* Build conjecture formula and negate it: Conjectures are taken disjunctively!!*/
+  for (Scan = Conjectures; !list_Empty(Scan); Scan = list_Cdr(Scan))
+    list_Rplacd(list_Car(Scan), (LIST)term_Create(fol_Not(), 
+						  list_List(list_PairSecond(list_Car(Scan)))));
+
+  clock_StopPassedTime(clock_INPUT);
+
+  if (top_InputFile) {
+    misc_CloseFile(InputStream,top_InputFile);
+    if (opts_IsSet(top_RemoveFileOptId))
+      remove(top_InputFile);
+  }
+
+  clock_StartCounter(clock_CNF);
+
+  if (list_Empty(InputClauses)) {
+    NAT Termcount;
+
+    Termcount  = 0;
+    
+    /* Create labels for formulae without them */
+    for (Scan = Axioms; !list_Empty(Scan); Scan = list_Cdr(Scan), Termcount++) {
+      if (list_PairFirst(list_Car(Scan)) == NULL) {
+	char L[100];
+	char* Label;
+	sprintf(L, "axiom%d", Termcount);
+	Label = string_StringCopy(L);
+	list_Rplaca(list_Car(Scan), Label);
+	if (flag_GetFlagValue(Flags, flag_DOCPROOF) &&
+	    flag_GetFlagValue(Flags, flag_PLABELS)) {
+	  printf("\nAdded label %s for axiom \n", Label);
+	  fol_PrettyPrintDFG((TERM) list_PairSecond(list_Car(Scan)));
+	}
+      }
+    }
+    Termcount  = 0;
+    for (Scan = Sorts; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+      char L[100];
+      char* Label;
+      sprintf(L, "declaration%d", Termcount);
+      Label = string_StringCopy(L);
+      list_Rplaca(list_Car(Scan), Label);
+      if (flag_GetFlagValue(Flags, flag_DOCPROOF) &&
+	  flag_GetFlagValue(Flags, flag_PLABELS)) {
+	printf("\nAdded label %s for declaration \n", Label);
+	fol_PrettyPrintDFG((TERM) list_PairSecond(list_Car(Scan)));
+      }
+      Sortlabellist = list_Cons(Label, Sortlabellist);
+    }
+    Axioms = list_Nconc(Axioms, Sorts);
+
+
+    if (flag_GetFlagValue(Flags, flag_APPLYDEFS) != flag_APPLYDEFSOFF) {
+      def_ExtractDefsFromTermlist(Search, Axioms, Conjectures); 
+      Conjectures = def_ApplyDefinitionToTermList(prfs_Definitions(Search),
+						  Conjectures, Flags,
+						  Precedence);
+    }
+
+    /* We must keep the list of symbols because they can't be freed in cnf_Flotter */
+    Symblist = list_Nil();
+
+    /* Axioms is list of pairs, conjectures is list of terms */
+    /* A ProofSearch object is only returned and the symbols kept in Symblist
+       if flag_INTERACTIVE is set */
+    FlotterSearch = cnf_Flotter(Axioms,Conjectures,&InputClauses, &Labellist,
+				TermLabelToClauselist, ClauseToTermLabellist,
+				Flags, Precedence, &Symblist);
+
+    InputClauses = clause_ListSortWeighed(InputClauses);
+    clause_SetCounter(1);
+    for (Scan = InputClauses; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
+      clause_NewNumber(list_Car(Scan));
+    }
+  }
+  else {
+    dfg_DeleteFormulaPairList(Axioms);
+    dfg_DeleteFormulaPairList(Sorts);
+    dfg_DeleteFormulaPairList(Conjectures);
+    if (flag_GetFlagValue(Flags, flag_APPLYDEFS) != flag_APPLYDEFSOFF) {
+      /* Extract list of definitions */
+      def_ExtractDefsFromClauselist(Search, InputClauses);
+      def_FlattenDefinitionsDestructive(Search);
+      for (Scan=prfs_Definitions(Search); !list_Empty(Scan); Scan=list_Cdr(Scan))
+	InputClauses = def_ApplyDefToClauselist(Search, (DEF) list_Car(Scan),
+						InputClauses, TRUE);
+    }
+  }
+
+  clock_StopPassedTime(clock_CNF);
+
+  if (top_CalledFlotter(argv[0]) || flag_GetFlagValue(Flags, flag_FLOTTER)) {
+    top_Flotter(argc,argv,InputClauses);
+    flag_SetFlagValue(Flags, flag_TIMELIMIT,   0);       /* Exit No Output */
+    flag_SetFlagValue(Flags, flag_INTERACTIVE, flag_INTERACTIVEOFF);
+    flag_SetFlagValue(Flags, flag_PPROBLEM,    flag_PPROBLEMOFF);
+  }
+
+  memory_Restrict(flag_GetFlagValue(Flags, flag_MEMORY));
+
+  do {
+    LIST deflist;
+    int  BoundApplied;
+    ProblemClauses = list_Nil();
+    LabelClauses   = list_Nil();
+    Result         = top_RESOURCE;
+
+    if (flag_GetFlagValue(Flags, flag_INTERACTIVE)) {
+      QueryPair = ia_GetNextRequest(InputStream, Flags);
+      /* A pair (<formula,labellist>) */
+      /* Get list of clauses derivable from formulae with labels in labellist */
+      if (list_Empty(QueryPair)) {
+	break;
+      }
+      for (Scan=list_PairSecond(QueryPair);!list_Empty(Scan);Scan=list_Cdr(Scan)) {
+	LIST l;
+	l = hsh_GetWithCompareFunc(TermLabelToClauselist, list_Car(Scan),
+				   (BOOL (*)(POINTER, POINTER)) cnf_LabelEqual,
+				   (unsigned long (*)(POINTER)) hsh_StringHashKey);
+
+	l = list_PointerDeleteDuplicates(list_Copy(l));
+	LabelClauses = list_Nconc(l, LabelClauses);
+      }
+      /* Get list of clauses derivable from sorts */
+      for (Scan=Sortlabellist; !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+	LIST l;
+	l = hsh_GetWithCompareFunc(TermLabelToClauselist, list_Car(Scan),
+				   (BOOL (*)(POINTER, POINTER)) cnf_LabelEqual,
+				   (unsigned long (*)(POINTER)) hsh_StringHashKey);
+
+	l = list_PointerDeleteDuplicates(list_Copy(l));
+	LabelClauses = list_Nconc(l, LabelClauses);
+      }	
+
+      /* For labelclauses copies are introduced */
+      /* So an update to the clause to term mapping is necessary */
+      for (Scan=LabelClauses; !list_Empty(Scan); Scan=list_Cdr(Scan)) {
+	CLAUSE C;
+	LIST l;
+	C = (CLAUSE) list_Car(Scan);
+	l = list_Copy(hsh_Get(ClauseToTermLabellist, C));
+	l = cnf_DeleteDuplicateLabelsFromList(l);
+	list_Rplaca(Scan, clause_Copy(C));
+	hsh_PutList(ClauseToTermLabellist, list_Car(Scan), l);
+      }
+      QueryClauses   = cnf_QueryFlotter(FlotterSearch, list_PairFirst(QueryPair),
+					&Symblist);
+      ProblemClauses = list_Nconc(QueryClauses, LabelClauses);
+
+      for (Scan=list_PairSecond(QueryPair); !list_Empty(Scan); Scan= list_Cdr(Scan))
+	string_StringFree(list_Car(Scan)); /* Free the label strings */
+      list_Delete(list_PairSecond(QueryPair));
+      list_PairFree(QueryPair);
+      clock_InitCounter(clock_OVERALL);
+      clock_StartCounter(clock_OVERALL);
+    }
+    else {
+      ProblemClauses = InputClauses;
+      InputClauses   = list_Nil();
+    }
+
+
+    prfs_SetSplitCounter(Search,flag_GetFlagValue(Flags, flag_SPLITS));
+    prfs_SetLoops(Search,flag_GetFlagValue(Flags, flag_LOOPS));
+    prfs_SetBacktrackedClauses(Search, 0);
+    BoundApplied = -1;
+    Search = top_ProofSearch(Search, ProblemClauses, InputFlags, UserPrecedence, &BoundApplied);
+  
+    if ((flag_GetFlagValue(Flags, flag_TIMELIMIT) == flag_TIMELIMITUNLIMITED ||
+	 flag_GetFlagValue(Flags, flag_TIMELIMIT) > clock_GetSeconds(clock_OVERALL)) &&
+	prfs_Loops(Search) != 0 &&
+	(BoundApplied == -1 || !list_Empty(prfs_EmptyClauses(Search)))) {
+      if (list_Empty(prfs_EmptyClauses(Search)))
+	Result = top_COMPLETION;
+      else
+	Result = top_PROOF;
+    }
+   
+    if (flag_GetFlagValue(Flags, flag_TIMELIMIT) != 0) {
+      /* Stop SPASS immediately */
+      printf("\nSPASS %s ", misc_VERSION);
+      fputs("\nSPASS beiseite: ", stdout);
+      switch (Result) {
+      case top_RESOURCE:
+	if (prfs_Loops(Search) != 0)
+	  fputs("Ran out of time.", stdout);
+	else
+	  fputs("Maximal number of loops exceeded.", stdout);
+	break;
+      case top_PROOF:
+	fputs("Proof found.", stdout);
+	break;
+      default:        /* Completion */
+	fputs("Completion found.", stdout);
+      }
+      printf("\nProblem: %s ",
+	     (top_InputFile != (char*)NULL ? top_InputFile : "Read from stdin."));
+      if (flag_GetFlagValue(Flags, flag_PSTATISTIC)) {
+	clock_StopPassedTime(clock_OVERALL);
+	printf("\nSPASS derived %d clauses,", prfs_DerivedClauses(Search));
+	printf(" backtracked %d clauses", prfs_BacktrackedClauses(Search));
+	printf(" and kept %d clauses.", prfs_KeptClauses(Search));
+	printf("\nSPASS allocated %lu KBytes.", memory_DemandedBytes()/1024);
+	fputs("\nSPASS spent\t", stdout);
+	clock_PrintTime(clock_OVERALL);
+	fputs(" on the problem.\n\t\t", stdout);
+	clock_PrintTime(clock_INPUT);
+	fputs(" for the input.\n\t\t", stdout);
+	clock_PrintTime(clock_CNF);
+	fputs(" for the FLOTTER CNF translation.\n\t\t", stdout);
+	clock_PrintTime(clock_INFERENCE);
+	fputs(" for inferences.\n\t\t", stdout);
+        clock_PrintTime(clock_BACKTRACK);
+	fputs(" for the backtracking.\n\t\t", stdout);
+	clock_PrintTime(clock_REDUCTION);
+	puts(" for the reduction.");
+      }
+      if (Result != top_PROOF &&
+	  flag_GetFlagValue(Flags, flag_FPMODEL) != flag_FPMODELOFF) {
+	FILE *Output;
+	char name[100];
+	const char * creator = "{*SPASS " misc_VERSION " *}";
+	BOOL PrintPotProductive;
+
+	strcpy(name, (top_InputFile != (char*)NULL ? top_InputFile : "SPASS"));
+	if (Result == top_COMPLETION)
+	  strcat(name, ".model");
+	else
+	  strcat(name, ".clauses");
+	Output = misc_OpenFile(name,"w");
+	PrintPotProductive = (flag_GetFlagValue(Flags, flag_FPMODEL) ==
+			      flag_FPMODELPOTENTIALLYPRODUCTIVECLAUSES);
+	if (Result == top_COMPLETION)
+	  clause_FPrintCnfFormulasDFGProblem(Output, PrintPotProductive,
+					     "{*Completion_by_SPASS*}",
+					     creator, "satisfiable",
+					     dfg_ProblemDescription(),
+					     prfs_WorkedOffClauses(Search),
+					     list_Nil(), Flags, Precedence);
+	else
+	  clause_FPrintCnfFormulasDFGProblem(Output, PrintPotProductive,
+					     "{*Clauses_generated_by_SPASS*}",
+					     creator, "unknown",
+					     dfg_ProblemDescription(),
+					     prfs_WorkedOffClauses(Search),
+					     prfs_UsableClauses(Search), Flags,
+					     Precedence);
+	misc_CloseFile(Output, name);
+	if (Result == top_COMPLETION)
+	  printf("\nCompletion printed to: %s\n", name);
+	else
+	  printf("\nClauses printed to: %s\n", name);
+      }
+    
+      if (flag_GetFlagValue(Flags, flag_DOCPROOF) && Result != top_RESOURCE) {
+	if (Result == top_COMPLETION) {
+	  puts("\n\n The saturated set of worked-off clauses is :");
+	  clause_ListPrint(prfs_WorkedOffClauses(Search));
+	}
+	else {
+	  LIST UsedClauses, UsedTerms;
+	  if (!top_InputFile)
+	    top_InputFile = "SPASS";
+	  UsedClauses = dp_PrintProof(Search, prfs_EmptyClauses(Search),
+				      top_InputFile);
+	  /* Find terms required for proof */
+	  UsedTerms = list_Nil();
+
+	  for (Scan = UsedClauses; !list_Empty(Scan); Scan = list_Cdr(Scan))
+	    if (clause_IsFromInput((CLAUSE) list_Car(Scan))) {
+	      LIST L;
+	      L = hsh_Get(ClauseToTermLabellist, list_Car(Scan));
+	      L = list_Copy(L);
+	      L = cnf_DeleteDuplicateLabelsFromList(L);
+	      UsedTerms = list_Nconc(UsedTerms, L);
+	    }
+	  list_Delete(UsedClauses);
+	  UsedTerms = cnf_DeleteDuplicateLabelsFromList(UsedTerms);
+	  fputs("\nFormulae used in the proof :", stdout);
+	  for (Scan = UsedTerms; !list_Empty(Scan); Scan = list_Cdr(Scan)) 
+	    if (!(strncmp((char*) list_Car(Scan), "_SORT_", 6) == 0))
+	      printf(" %s", (char*) list_Car(Scan));
+	  putchar('\n');
+	  list_Delete(UsedTerms);
+	}
+      }
+    }
+    
+    /* Delete mapping for the clause copies of the labelclauses */
+    for (Scan = LabelClauses; !list_Empty(Scan); Scan=list_Cdr(Scan))
+      hsh_DelItem(ClauseToTermLabellist, list_Car(Scan));
+    
+    list_Delete(ProblemClauses);
+ 
+    fflush(stdout);
+
+    /* Keep definitions */
+    deflist = prfs_Definitions(Search);
+    prfs_SetDefinitions(Search, list_Nil());
+    prfs_Clean(Search);
+    prfs_SetDefinitions(Search, deflist);
+
+    symbol_TransferPrecedence(InputPrecedence, Precedence);
+    if (flag_GetFlagValue(Flags, flag_PPROBLEM))
+      fputs("\n--------------------------SPASS-STOP------------------------------", stdout);
+  } while (flag_GetFlagValue(Flags, flag_INTERACTIVE) &&
+	   (flag_GetFlagValue(Flags, flag_TIMELIMIT) != 0));
+
+  for (Scan = InputClauses; !list_Empty(Scan); Scan=list_Cdr(Scan))
+    clause_OrientAndReInit(list_Car(Scan), Flags, Precedence);
+
+  /* Cleanup Flotter data structures */
+  if (flag_GetFlagValue(Flags, flag_INTERACTIVE)) {
+    if (flag_GetFlagValue(Flags, flag_DOCPROOF))
+      list_Delete(Symblist);
+    else 
+      symbol_DeleteSymbolList(Symblist);
+    /*  symbol_ResetSkolemIndex(); */
+    if (FlotterSearch != NULL) 
+      prfs_Delete(FlotterSearch);
+  }
+  if (flag_GetFlagValue(Flags, flag_PFLAGS)) {
+    putchar('\n');
+    flag_Print(Flags);
+  }
+  if (flag_GetFlagValue(Flags, flag_DOCPROOF)) {
+    hsh_Delete(TermLabelToClauselist);
+    hsh_Delete(ClauseToTermLabellist);
+  }
+  for (Scan = Labellist; !list_Empty(Scan); Scan = list_Cdr(Scan))
+    string_StringFree(list_Car(Scan));
+  list_Delete(Labellist);
+  list_Delete(Sortlabellist);
+  list_Delete(UserPrecedence);
+
+  cnf_Free(Flags);
+
+  prfs_Delete(Search);
+  clause_DeleteClauseList(InputClauses);
+  flag_DeleteStore(InputFlags);
+  symbol_DeletePrecedence(InputPrecedence);
+
+  cc_Free();
+  ana_Free();
+  sort_Free();
+  unify_Free();
+  cont_Free();
+  fol_Free();
+  symbol_FreeAllSymbols();
+  dfg_Free();
+  opts_Free();
+#ifdef CHECK
+  memory_Print();
+  memory_PrintLeaks();
+#endif
+  putchar('\n');
+  return 0;
+}
diff --git a/test/spass/unify.c b/test/spass/unify.c
new file mode 100644
index 0000000000000000000000000000000000000000..14cc7a6a75f5db24d3e6a9890e347be90f9acdcc
--- /dev/null
+++ b/test/spass/unify.c
@@ -0,0 +1,857 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                STANDARD UNIFICATION                    * */
+/* *                                                        * */
+/* *  $Module:   UNIFY                                      * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 2000, 2001            * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "unify.h"
+
+/**************************************************************/
+/* ********************************************************** */
+/* *							    * */
+/* *  INITIALIZATION           			            * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+void unify_Init(void)
+/**********************************************************
+  INPUT:   None.
+  RETURNS: None.
+  EFFECT:  Initializes the unify module.
+********************************************************/
+{
+
+}
+
+void unify_Free(void)
+/**********************************************************
+  INPUT:   None.
+  RETURNS: None.
+  EFFECT:  Frees internal structures of the unify module.
+********************************************************/
+{
+
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *							    * */
+/* *  MISC FUNCTIONS                     	            * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *							    * */
+/* *  OCCUR CHECK            			            * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL unify_OccurCheckCom(SYMBOL Top, CONTEXT Context, TERM Term)
+/**********************************************************
+  INPUT:   A variable symbol, a context, and a term.
+  RETURNS: TRUE if there is a occur check failure with respect
+           to the variable symbol <Top> and <Term>.
+	   The search is started in <Term>
+***********************************************************/
+{
+  int  Bottom;
+  LIST Args;
+
+  Bottom = stack_Bottom();
+
+  for (;;) {
+
+    if (term_IsVariable(Term)) {
+      if (symbol_Equal(Top, term_TopSymbol(Term))) {
+	stack_SetBottom(Bottom);
+	return TRUE;
+      } else if (cont_VarIsBound(Context, term_TopSymbol(Term))) {
+	Term = cont_ContextBindingTerm(Context, term_TopSymbol(Term));
+	continue;
+      }
+
+    } else if (term_IsComplex(Term)) {
+
+      Args = term_ArgumentList(Term);
+      if (!list_Empty(list_Cdr(Args)))
+	stack_Push(list_Cdr(Args));
+
+      Term = list_Car(Args);
+      continue;
+    }
+
+    if (stack_Empty(Bottom))
+      return FALSE;
+    else {
+      Args = (LIST)stack_PopResult();
+      Term = list_Car(Args);
+      if (!list_Empty(list_Cdr(Args)))
+	stack_Push(list_Cdr(Args));
+    }
+  }
+}
+
+
+BOOL unify_OccurCheck(CONTEXT CTop, SYMBOL Top, CONTEXT CTerm, TERM Term)
+/**********************************************************
+  INPUT:   A context, a variable symbol, a context, and a term.
+  RETURNS: TRUE if there is a occur check failure with respect
+           to the variable symbol <Top> and <Term>.
+	   The search is started in <Term>
+***********************************************************/
+{
+  int    Bottom;
+  LIST   Args;
+  SYMBOL TermTop;
+
+  Bottom = stack_Bottom();
+
+  for (;;) {
+
+    if (term_IsVariable(Term)) {
+
+      TermTop = term_TopSymbol(Term);
+
+      if ((CTop == CTerm) && (symbol_Equal(Top, TermTop))) {
+	stack_SetBottom(Bottom);
+	return TRUE;
+      } else if (cont_VarIsBound(CTerm, TermTop)) {
+	Term  = cont_ContextBindingTerm(CTerm, TermTop);
+	CTerm = cont_ContextBindingContext(CTerm, TermTop);
+	continue;
+      }
+    } else if (term_IsComplex(Term)) {
+
+      Args = term_ArgumentList(Term);
+      if (!list_Empty(list_Cdr(Args))) {
+	stack_Push(CTerm);
+	stack_Push(list_Cdr(Args));
+      }
+      Term = list_Car(Args);
+      continue;
+
+    }
+
+    if (stack_Empty(Bottom))
+      return FALSE;
+    else {
+      Args = (LIST)stack_PopResult();
+      Term = list_Car(Args);
+      CTerm = (CONTEXT)stack_Top();
+      if (list_Empty(list_Cdr(Args)))
+	stack_Pop();
+      else
+	stack_Push(list_Cdr(Args));
+    }
+  }
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *							    * */
+/* *  UNIFICATION           			            * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL unify_Unify(CONTEXT CtL, TERM TermL, CONTEXT CtR, TERM TermR)
+/**********************************************************
+  INPUT:   Two terms which may contain the same variable symbols.
+           Equal variable symbols are interpreted different in
+	   <TermL> and <TermR>, respectively.
+  RETURNS: TRUE, if <TermL> and <TermR> are unifiable, FALSE otherwise.
+  CAUTION: None.
+***********************************************************/
+{
+  CONTEXT CHelp;
+  LIST    ArgsL, ArgsR;
+  int     Bottom;
+  BOOL    Bound;
+
+  Bound  = FALSE;
+  Bottom = stack_Bottom();
+
+  for (;;) {
+
+    while (term_IsVariable(TermL) &&
+	   cont_VarIsBound(CtL, term_TopSymbol(TermL))) {
+      CHelp = cont_ContextBindingContext(CtL, term_TopSymbol(TermL));
+      TermL = cont_ContextBindingTerm(CtL, term_TopSymbol(TermL));
+      CtL   = CHelp;
+    }
+
+    while (term_IsVariable(TermR) &&
+	   cont_VarIsBound(CtR, term_TopSymbol(TermR))) {
+      CHelp = cont_ContextBindingContext(CtR, term_TopSymbol(TermR));
+      TermR = cont_ContextBindingTerm(CtR, term_TopSymbol(TermR));
+      CtR   = CHelp;
+    }
+
+    /* Caution: Bindings from variable to variable are made with priority
+       from the right context into the left context. */
+
+    if (term_IsVariable(TermL)) {
+      if (term_IsVariable(TermR)) {
+	if (!(CtL == CtR && term_EqualTopSymbols(TermL, TermR)))
+	  Bound = cont_CreateBinding(CtR, term_TopSymbol(TermR), CtL, TermL);
+      } else if (Bound && unify_OccurCheck(CtL, term_TopSymbol(TermL), CtR, TermR)) {
+	stack_SetBottom(Bottom);
+	return FALSE;
+      }	else
+	Bound = cont_CreateBinding(CtL, term_TopSymbol(TermL), CtR, TermR);
+
+    } else if (term_IsVariable(TermR)) {
+      if (Bound && unify_OccurCheck(CtR, term_TopSymbol(TermR), CtL, TermL)) {
+	stack_SetBottom(Bottom);
+	return FALSE;
+      }	else
+	Bound = cont_CreateBinding(CtR, term_TopSymbol(TermR), CtL, TermL);
+
+    } else if (term_EqualTopSymbols(TermL, TermR)) {
+      if (term_IsComplex(TermL) && TermL != TermR) {
+	ArgsL = term_ArgumentList(TermL);
+	ArgsR = term_ArgumentList(TermR);
+	if (!list_Empty(list_Cdr(ArgsL))) {
+	  stack_Push(CtL);
+	  stack_Push(CtR);
+	  stack_Push(list_Cdr(ArgsL));
+	  stack_Push(list_Cdr(ArgsR));
+	}
+	TermL = list_Car(ArgsL);
+	TermR = list_Car(ArgsR);
+	continue;
+      }
+    } else {
+      stack_SetBottom(Bottom);
+      return FALSE;
+    }
+
+    if (stack_Empty(Bottom))
+      return TRUE;
+    else {
+      ArgsR = stack_PopResult();
+      ArgsL = stack_PopResult();
+      TermR = list_Car(ArgsR);
+      TermL = list_Car(ArgsL);
+      CtR   = (CONTEXT)stack_Top();
+      CtL   = (CONTEXT)stack_NthTop(1);
+      if (list_Empty(list_Cdr(ArgsL)))
+	stack_NPop(2);
+      else {
+	stack_Push(list_Cdr(ArgsL));
+	stack_Push(list_Cdr(ArgsR));
+      }
+    }
+  }
+}
+
+BOOL unify_UnifyCom(CONTEXT Context, TERM TermL, TERM TermR)
+/**********************************************************
+  INPUT:   Two terms which may contain the same variable symbols.
+           Equal variable symbols are interpreted equally in
+	   <TermL> and <TermR>, respectively.
+  RETURNS: TRUE, if <TermL> and <TermR> are unifiable, FALSE otherwise.
+  CAUTION: None.
+***********************************************************/
+{
+  LIST ArgsL, ArgsR;
+  int  Bottom;
+
+  Bottom = stack_Bottom();
+
+  for (;;) {
+
+    while (term_IsVariable(TermL) &&
+	   cont_VarIsBound(Context, term_TopSymbol(TermL)))
+      TermL = cont_ContextBindingTerm(Context, term_TopSymbol(TermL));
+
+    while (term_IsVariable(TermR) &&
+	   cont_VarIsBound(Context, term_TopSymbol(TermR)))
+      TermR = cont_ContextBindingTerm(Context, term_TopSymbol(TermR));
+
+    if (term_EqualTopSymbols(TermL, TermR)) {
+      if (term_IsComplex(TermL) && TermL != TermR) {
+	ArgsL = term_ArgumentList(TermL);
+	ArgsR = term_ArgumentList(TermR);
+	if (!list_Empty(list_Cdr(ArgsL))) {
+	  stack_Push(list_Cdr(ArgsL));
+	  stack_Push(list_Cdr(ArgsR));
+	}
+	TermL = list_Car(ArgsL);
+	TermR = list_Car(ArgsR);
+	continue;
+      }
+    } else if (term_IsVariable(TermL)) {
+      if (term_IsVariable(TermR))
+	cont_CreateBinding(Context, term_TopSymbol(TermL), Context, TermR);
+      else if (unify_OccurCheckCom(term_TopSymbol(TermL), Context, TermR)) {
+	stack_SetBottom(Bottom);
+	return FALSE;
+      } else
+	cont_CreateBinding(Context, term_TopSymbol(TermL), Context, TermR);
+      
+    } else if (term_IsVariable(TermR)) {
+      if (unify_OccurCheckCom(term_TopSymbol(TermR), Context, TermL)) {
+	stack_SetBottom(Bottom);
+	return FALSE;
+      }	else
+	cont_CreateBinding(Context, term_TopSymbol(TermR), Context, TermL);
+
+    } else {
+      stack_SetBottom(Bottom);
+      return FALSE;
+    }
+
+    if (stack_Empty(Bottom))
+      return TRUE;
+    else {
+      ArgsR = stack_PopResult();
+      ArgsL = stack_PopResult();
+      TermR = list_Car(ArgsR);
+      TermL = list_Car(ArgsL);
+      if (!list_Empty(list_Cdr(ArgsL))) {
+	stack_Push(list_Cdr(ArgsL));
+	stack_Push(list_Cdr(ArgsR));
+      }
+    }
+  }
+}
+
+
+
+BOOL unify_UnifyNoOC(CONTEXT CtL, TERM TermL, CONTEXT CtR, TERM TermR)
+/**********************************************************
+  INPUT:   Two terms which may contain the same variable symbols.
+           Equal variable symbols are interpreted different in
+	   <TermL> and <TermR>, respectively.
+  RETURNS: TRUE, if <TermL> and <TermR> are unifiable, FALSE otherwise.
+  CAUTION: None.
+***********************************************************/
+{
+  CONTEXT CHelp;
+  LIST    ArgsL, ArgsR;
+  int     Bottom;
+
+  Bottom = stack_Bottom();
+
+  for (;;) {
+
+    while (term_IsVariable(TermL) &&
+	   cont_VarIsBound(CtL, term_TopSymbol(TermL))) {
+      CHelp = cont_ContextBindingContext(CtL, term_TopSymbol(TermL));
+      TermL = cont_ContextBindingTerm(CtL, term_TopSymbol(TermL));
+      CtL   = CHelp;
+    }
+
+    while (term_IsVariable(TermR) &&
+	   cont_VarIsBound(CtR, term_TopSymbol(TermR))) {
+      CHelp = cont_ContextBindingContext(CtR, term_TopSymbol(TermR));
+      TermR = cont_ContextBindingTerm(CtR, term_TopSymbol(TermR));
+      CtR   = CHelp;
+    }
+
+    /* Caution: Bindings from variable to variable are made with priority
+       from the right context into the left context. */
+
+    if (term_IsVariable(TermL)) {
+      if (term_IsVariable(TermR)) {
+	if (!(CtL == CtR && term_EqualTopSymbols(TermL, TermR)))
+	  cont_CreateBinding(CtR, term_TopSymbol(TermR), CtL, TermL);
+      } else 
+	cont_CreateBinding(CtL, term_TopSymbol(TermL), CtR, TermR);
+
+    } else if (term_IsVariable(TermR))
+      cont_CreateBinding(CtR, term_TopSymbol(TermR), CtL, TermL);
+
+    else if (term_EqualTopSymbols(TermL, TermR)) {
+      if (term_IsComplex(TermL) && TermL != TermR) {
+	ArgsL = term_ArgumentList(TermL);
+	ArgsR = term_ArgumentList(TermR);
+	if (!list_Empty(list_Cdr(ArgsL))) {
+	  stack_Push(CtL);
+	  stack_Push(CtR);
+	  stack_Push(list_Cdr(ArgsL));
+	  stack_Push(list_Cdr(ArgsR));
+	}
+	TermL = list_Car(ArgsL);
+	TermR = list_Car(ArgsR);
+	continue;
+      }
+    } else {
+      stack_SetBottom(Bottom);
+      return FALSE;
+    }
+
+    if (stack_Empty(Bottom))
+      return TRUE;
+    else {
+      ArgsR = stack_PopResult();
+      ArgsL = stack_PopResult();
+      TermR = list_Car(ArgsR);
+      TermL = list_Car(ArgsL);
+      CtR   = (CONTEXT) stack_Top();
+      CtL   = (CONTEXT) stack_NthTop(1);
+      if (list_Empty(list_Cdr(ArgsL)))
+	stack_NPop(2);
+      else {
+	stack_Push(list_Cdr(ArgsL));
+	stack_Push(list_Cdr(ArgsR));
+      }
+    }
+  }
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *							    * */
+/* *  UNIFICATION WITH FULL OCCUR CHECK	(recursive)         * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL unify_UnifyAllOC(CONTEXT IndexContext, CONTEXT CtL, TERM TermL, CONTEXT CtR, TERM TermR)
+{
+  while (term_IsVariable(TermL)) {
+    SYMBOL TermTop;
+
+    TermTop = term_TopSymbol(TermL);
+
+    if (cont_VarIsBound(CtL, TermTop)) {
+      CONTEXT CHelp;
+
+      CHelp = cont_ContextBindingContext(CtL, TermTop);
+      TermL = cont_ContextBindingTerm(CtL, TermTop);
+      CtL   = CHelp;
+    } else
+      break;
+  }
+
+  while (term_IsVariable(TermR)) {
+    SYMBOL TermTop;
+
+    TermTop = term_TopSymbol(TermR);
+
+    if (cont_VarIsBound(CtR, TermTop)) {
+      CONTEXT CHelp;
+
+      CHelp = cont_ContextBindingContext(CtR, TermTop);
+      TermR = cont_ContextBindingTerm(CtR, TermTop);
+      CtR   = CHelp;
+    } else
+      break;
+  }
+  
+  if (term_IsVariable(TermL)) {
+    
+    if (term_IsVariable(TermR)) {
+      if ((CtL != CtR || !term_EqualTopSymbols(TermL, TermR))) {
+	if (term_IsIndexVariable(TermL))
+	  cont_CreateBinding(CtL, term_TopSymbol(TermL), CtR, TermR);
+	else 
+	  if (term_IsIndexVariable(TermR) || (CtR == IndexContext))
+	    cont_CreateBinding(CtR, term_TopSymbol(TermR), CtL, TermL);
+	  else
+	    cont_CreateBinding(CtL, term_TopSymbol(TermL), CtR, TermR);
+      }
+      return TRUE;
+    } 
+    else 
+      if (unify_OccurCheck(CtL, term_TopSymbol(TermL), CtR, TermR))
+	return FALSE;
+      else {
+	cont_CreateBinding(CtL, term_TopSymbol(TermL), CtR, TermR);
+	return TRUE;
+      }
+  } 
+  else 
+    if (term_IsVariable(TermR)) { 
+      if (unify_OccurCheck(CtR, term_TopSymbol(TermR), CtL, TermL))
+	return FALSE;
+      else {
+	cont_CreateBinding(CtR, term_TopSymbol(TermR), CtL, TermL);
+	return TRUE;
+      }
+    } 
+    else 
+      if (term_EqualTopSymbols(TermL, TermR)) {
+	if (term_IsComplex(TermL)) {
+	  LIST ArgL, ArgR;
+	  for (ArgL = term_ArgumentList(TermL), ArgR = term_ArgumentList(TermR);
+	       !list_Empty(ArgL);
+	       ArgL = list_Cdr(ArgL), ArgR = list_Cdr(ArgR))
+	    if (!unify_UnifyAllOC(IndexContext, CtL, list_Car(ArgL), CtR, list_Car(ArgR)))
+	      return FALSE;
+	}
+	return TRUE;
+      } 
+      else
+	return FALSE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *							    * */
+/* *  GENERALIZATION TEST      			            * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL unify_Match(CONTEXT Context, TERM TermL, TERM TermR)
+{
+  if (term_IsVariable(TermL)) {
+    if (cont_VarIsBound(Context, term_TopSymbol(TermL)))
+      return term_Equal(cont_ContextBindingTerm(Context, term_TopSymbol(TermL)), TermR);
+    else {
+      cont_CreateBinding(Context, term_TopSymbol(TermL), cont_InstanceContext(), TermR);
+      return TRUE;
+    }
+  } else if (term_EqualTopSymbols(TermL, TermR)) {
+    if (term_IsComplex(TermL)) {
+      LIST ArgL;
+      LIST ArgR;
+      for (ArgL = term_ArgumentList(TermL), ArgR = term_ArgumentList(TermR);
+	   !list_Empty(ArgL);
+	   ArgL = list_Cdr(ArgL), ArgR = list_Cdr(ArgR))
+	if (!unify_Match(Context, list_Car(ArgL), list_Car(ArgR)))
+	  return FALSE;
+    }
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+BOOL unify_MatchFlexible(CONTEXT Context, TERM TermL, TERM TermR)
+/**************************************************************
+  INPUT:   Two terms where symbols with flexible arity are allowed.
+  RETURNS: TRUE if <TermL> matches <TermR>.        
+***************************************************************/
+{
+  if (term_IsVariable(TermL)) {
+    if (cont_VarIsBound(Context, term_TopSymbol(TermL)))
+      return term_Equal(cont_ContextBindingTerm(Context, term_TopSymbol(TermL)), TermR);
+    else {
+      cont_CreateBinding(Context, term_TopSymbol(TermL), cont_InstanceContext(), TermR);
+      return TRUE;
+    }
+  } else 
+    if (term_EqualTopSymbols(TermL, TermR) 
+	&& list_Length(term_ArgumentList(TermL)) == list_Length(term_ArgumentList(TermR))) {
+      if (term_IsComplex(TermL)) {
+	LIST ArgL;
+	LIST ArgR;
+	for (ArgL = term_ArgumentList(TermL), ArgR = term_ArgumentList(TermR);
+	     !list_Empty(ArgL);
+	     ArgL = list_Cdr(ArgL), ArgR = list_Cdr(ArgR))
+	  if (!unify_MatchFlexible(Context, list_Car(ArgL), list_Car(ArgR)))
+	    return FALSE;
+      }
+      return TRUE;
+    } 
+    else
+      return FALSE;
+}
+
+
+void unify_EstablishMatcher(CONTEXT Context, SUBST Subst)
+{
+  while (subst_Exist(Subst)) {
+    /* Index to query */
+    cont_CreateBinding(Context, subst_Dom(Subst), cont_InstanceContext(), subst_Cod(Subst));
+    Subst = subst_Next(Subst);
+  }
+}
+
+
+BOOL unify_MatchBindingsHelp(const CONTEXT IndexContext, TERM TermL, CONTEXT CtR, TERM TermR)
+{
+  while (term_IsVariable(TermR)) {
+    SYMBOL TermTop;
+
+    TermTop = term_TopSymbol(TermR);
+
+    if (symbol_IsIndexVariable(TermTop))
+      CtR = IndexContext;
+    else if (CtR == cont_InstanceContext())
+      break;
+
+    if (cont_VarIsBound(CtR, TermTop)) {
+      CONTEXT CHelp;
+
+      CHelp = cont_ContextBindingContext(CtR, TermTop);
+      TermR = cont_ContextBindingTerm(CtR, TermTop);
+      CtR   = CHelp;
+    } else
+      break;
+  }
+
+  if (term_IsVariable(TermL)) {
+    /* Assertion: Variables of 'TermL' are bound in the index context only. */
+
+    if (cont_VarIsBound(IndexContext, term_TopSymbol(TermL)))
+      return
+	cont_TermEqualModuloBindings(IndexContext,
+					cont_ContextBindingContext(IndexContext,
+								      term_TopSymbol(TermL)),
+					cont_ContextBindingTerm(IndexContext,
+								   term_TopSymbol(TermL)),
+					CtR,
+					TermR);
+    else {
+      cont_CreateBinding(IndexContext, term_TopSymbol(TermL), CtR, TermR);
+      return TRUE;
+    }
+  } else if (term_EqualTopSymbols(TermL, TermR)) {
+    if (term_IsComplex(TermL)) {
+      LIST ArgL;
+      LIST ArgR;
+
+      for (ArgL = term_ArgumentList(TermL), ArgR = term_ArgumentList(TermR);
+	   !list_Empty(ArgL);
+	   ArgL = list_Cdr(ArgL), ArgR = list_Cdr(ArgR))
+	if (!unify_MatchBindingsHelp(IndexContext, list_Car(ArgL), CtR, list_Car(ArgR)))
+	  return FALSE;
+    }
+
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+
+BOOL unify_MatchBindings(const CONTEXT IndexContext, TERM TermL, TERM TermR)
+{
+  return unify_MatchBindingsHelp(IndexContext, TermL, cont_InstanceContext(), TermR);
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *							    * */
+/* *  INSTANCE TEST      			            * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL unify_MatchReverse(const CONTEXT IndexContext, TERM TermL,	CONTEXT CtR, 
+			TERM TermR)
+/*********************************************************
+  INPUT:   'TermL' is in IndexContext and the codomain of a subst.,
+           'CtR' is the context of 'TermR' which is the codomain of a subst.
+           obtained by a variable binding, 'Bindings' is
+           the number of established bindings.
+  RETURNS: TRUE, if 'TermL' is an instance of 'TermR';
+           FALSE, otherwise.
+**********************************************************/
+{
+  while (term_IsVariable(TermR)) {
+    SYMBOL TermTop;
+
+    TermTop = term_TopSymbol(TermR);
+
+    if (symbol_IsIndexVariable(TermTop))
+      CtR = IndexContext;
+    else if (CtR == cont_InstanceContext())
+      break;
+
+    if (cont_VarIsBound(CtR, TermTop)) {
+      CONTEXT CHelp;
+
+      CHelp = cont_ContextBindingContext(CtR, TermTop);
+      TermR = cont_ContextBindingTerm(CtR, TermTop);
+      CtR   = CHelp;
+    } else
+      break;
+  }
+
+  if (term_IsVariable(TermL)) {
+    if ((CtR == cont_InstanceContext()) && term_EqualTopSymbols(TermL, TermR))
+      /* 'TermL' and 'TermR' are exactly the same variables (via bindings),
+	 therefore do not bind them, just return positive. */
+      return TRUE;
+
+    else if (term_IsIndexVariable(TermL)) {
+      cont_CreateBinding(IndexContext, term_TopSymbol(TermL), CtR, TermR);
+      return TRUE;
+
+    } else if (term_IsVariable(TermR) &&
+	       (term_IsIndexVariable(TermR) || (CtR == IndexContext))) {
+      cont_CreateBinding(IndexContext, term_TopSymbol(TermR), cont_InstanceContext(), TermL);
+      return TRUE;
+
+    } else
+      return FALSE;
+
+  } else if (term_IsVariable(TermR)) {
+    if (term_IsIndexVariable(TermR) || (CtR == IndexContext)) {
+      cont_CreateBinding(IndexContext, term_TopSymbol(TermR), cont_InstanceContext(), TermL);
+      return TRUE;
+    } else
+      return FALSE;
+
+  } else if (term_EqualTopSymbols(TermL, TermR)) {
+    
+    if (term_IsComplex(TermL)) {
+      LIST ArgL, ArgR;
+      for (ArgL = term_ArgumentList(TermL), ArgR = term_ArgumentList(TermR);
+	   !list_Empty(ArgL);
+	   ArgL = list_Cdr(ArgL), ArgR = list_Cdr(ArgR))
+	if (!unify_MatchReverse(IndexContext,
+				list_Car(ArgL),
+				CtR,
+				list_Car(ArgR)))
+	  return FALSE;
+    }
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *							    * */
+/* *  VARIATION TEST      			            * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+BOOL unify_Variation(const CONTEXT Context, TERM TermL, TERM TermR)
+{
+  if (term_IsVariable(TermL)) {
+    if (term_EqualTopSymbols(TermL, TermR))
+      /* TermL and TermR are in different contexts
+	 but both are term variables which do not need to be variated.
+	 Index variables cannot occur in TermR
+	 which is the term to be inserted. */
+      return TRUE;
+    else if (term_IsIndexVariable(TermL)) {
+      if (cont_VarIsBound(Context, term_TopSymbol(TermL)))
+	return term_Equal(cont_ContextBindingTerm(Context, term_TopSymbol(TermL)), TermR);
+      else {
+	/* Index to query */
+	cont_CreateBinding(Context, term_TopSymbol(TermL), Context, TermR);
+	return TRUE;
+      }
+    }
+    else
+      return FALSE;
+
+  } else if (term_EqualTopSymbols(TermL, TermR)) {
+    if (term_IsComplex(TermL)) {
+      LIST ArgL;
+      LIST ArgR;
+      for (ArgL = term_ArgumentList(TermL), ArgR = term_ArgumentList(TermR);
+	   !list_Empty(ArgL);
+	   ArgL = list_Cdr(ArgL), ArgR = list_Cdr(ArgR))
+	if (!unify_Variation(Context, list_Car(ArgL), list_Car(ArgR)))
+	  return FALSE;
+    }
+    return TRUE;
+  } else 
+    return FALSE;
+}
+
+
+/**************************************************************/
+/* ********************************************************** */
+/* *							    * */
+/* *  COMMON GENERALIZATIONS   			            * */
+/* *							    * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+TERM unify_ComGenLinear(const CONTEXT IndexContext,
+			SUBST* SubstL, TERM TermL, SUBST* SubstR, TERM TermR)
+{
+  if (term_IsIndexVariable(TermR)) {
+    *SubstL = subst_Add(term_TopSymbol(TermR), term_Copy(TermL), *SubstL);
+
+    return term_Copy(TermR);
+  
+  } else if (term_EqualTopSymbols(TermL, TermR)) {
+   
+    LIST ArgList, ArgL, ArgR;
+
+    ArgList   = list_Nil();
+    for (ArgL = term_ArgumentList(TermL), ArgR = term_ArgumentList(TermR);
+	 !list_Empty(ArgL);
+	 ArgL = list_Cdr(ArgL), ArgR = list_Cdr(ArgR))
+      ArgList = list_Nconc(ArgList,
+			   list_List(unify_ComGenLinear(IndexContext,
+							SubstL,
+							list_Car(ArgL),
+							SubstR,
+							list_Car(ArgR))));
+    return term_Create(term_TopSymbol(TermL), ArgList);
+    
+  } else {
+    
+    SYMBOL Symbol;
+    
+    Symbol  = cont_NextIndexVariable(IndexContext);
+
+    *SubstL = subst_Add(Symbol, term_Copy(TermL), *SubstL);
+    *SubstR = subst_Add(Symbol, term_Copy(TermR), *SubstR);
+    
+    return term_Create(Symbol, list_Nil());
+  }
+}
+
diff --git a/test/spass/unify.h b/test/spass/unify.h
new file mode 100644
index 0000000000000000000000000000000000000000..92c93989360ccb93053f8ed68dbc4547e58a1c24
--- /dev/null
+++ b/test/spass/unify.h
@@ -0,0 +1,119 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *                STANDARD UNIFICATION                    * */
+/* *                                                        * */
+/* *  $Module:   UNIFY                                      * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1997, 1998, 2001                  * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#ifndef _UNIFY_
+#define _UNIFY_
+
+/**************************************************************/
+/* Includes                                                   */
+/**************************************************************/
+
+#include "term.h"
+#include "symbol.h"
+#include "list.h"
+#include "context.h"
+#include "subst.h"
+
+/**************************************************************/
+/* Functions for Initialization and Controlling               */
+/**************************************************************/
+           
+void unify_Init(void);
+void unify_Free(void);
+
+/**************************************************************/
+/* Functions for Misc                                         */
+/**************************************************************/
+
+/**************************************************************/
+/* Functions for Occur Check                                  */
+/**************************************************************/
+
+BOOL unify_OccurCheckCom(SYMBOL, CONTEXT, TERM);
+BOOL unify_OccurCheck(CONTEXT, SYMBOL, CONTEXT, TERM);
+
+/**************************************************************/
+/* Functions for Unification                                  */
+/**************************************************************/
+
+BOOL unify_Unify(CONTEXT, TERM, CONTEXT, TERM);
+BOOL unify_UnifyCom(CONTEXT, TERM, TERM);
+BOOL unify_UnifyNoOC(CONTEXT, TERM, CONTEXT, TERM);
+BOOL unify_UnifyAllOC(CONTEXT, CONTEXT, TERM, CONTEXT, TERM);
+
+/**************************************************************/
+/* Functions for Generalization Test                          */
+/**************************************************************/
+
+BOOL unify_Match(CONTEXT, TERM, TERM);
+BOOL unify_MatchFlexible(CONTEXT, TERM, TERM);
+void unify_EstablishMatcher(CONTEXT, SUBST);
+BOOL unify_MatchBindings(const CONTEXT, TERM, TERM);
+
+/**************************************************************/
+/* Functions for Instance Test                                */
+/**************************************************************/
+
+BOOL unify_MatchReverse(const CONTEXT, TERM, CONTEXT, TERM);
+
+/**************************************************************/
+/* Functions for Variation Test                               */
+/**************************************************************/
+
+BOOL unify_Variation(const CONTEXT, TERM, TERM);
+
+/**************************************************************/
+/* Functions for Computing MSCGs                              */
+/**************************************************************/
+
+TERM unify_ComGenLinear(const CONTEXT, SUBST*, TERM, SUBST*, TERM);
+
+/**************************************************************/
+/* Functions for Debugging                                    */
+/**************************************************************/
+
+#endif
diff --git a/test/spass/vector.c b/test/spass/vector.c
new file mode 100644
index 0000000000000000000000000000000000000000..bd16424a7b24661cd0c1e48a013721de397c9d05
--- /dev/null
+++ b/test/spass/vector.c
@@ -0,0 +1,120 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *             GLOBAL SYSTEM VECTOR                       * */
+/* *                                                        * */
+/* *  $Module:   VECTOR                                     * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 2000, 2001 MPI fuer Informatik    * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+#include "vector.h"
+
+/**************************************************************/
+/* Global Variables                                           */
+/**************************************************************/
+
+VECTOR vec_VECTOR;
+int    vec_MAX;
+
+
+/**************************************************************/
+/* Functions                                                  */
+/**************************************************************/
+
+void vec_Swap(int i, int j)
+/**********************************************************
+  INPUT:   Two integers i and j which designate the i-th and
+           the j-th cell of the vector.
+  RETURNS: None.
+  CAUTION: The values in the i-th and the j-th cell in the
+            vector are interchanged.
+********************************************************/
+{
+  POINTER help;
+
+  help  = vec_GetNth(i);
+  vec_PutNth(i, vec_GetNth(j));
+  vec_PutNth(j, help);
+ 
+}
+
+
+void vec_PrintSel(int beg, int end, void (*ElementPrint)(POINTER))
+/**********************************************************
+  INPUT:   An int for the start position, an int for
+           the end position and a print function for
+	   elements.
+  RETURNS: None.
+  EFFECT:  Writes the vector from beg to end to stdout.
+  CAUTION: None.
+********************************************************/
+{
+  int i;
+
+  if (vec_ActMax() > 0) {
+    for (i = beg; i < end; i++){
+      printf("Entry %d:\t",i);
+      ElementPrint(vec_GetNth(i));
+      putchar('\n');
+    }
+  } else
+    puts("Vector is empty");
+}
+
+
+void vec_PrintAll(void (*ElementPrint)(POINTER))
+/**********************************************************
+  INPUT:   A print function for the elements of the vector.
+  RETURNS: None.
+  EFFECT:  Writes the vector to stdout.
+  CAUTION: None.
+********************************************************/
+{
+  int i;
+
+  if (vec_ActMax() > 0) {
+    for (i = 0; i < vec_ActMax(); i++) {
+      printf("Entry %d:\t", i);
+      ElementPrint(vec_GetNth(i));
+      putchar('\n');
+    }
+  } else
+    puts("Vector is empty");
+}
diff --git a/test/spass/vector.h b/test/spass/vector.h
new file mode 100644
index 0000000000000000000000000000000000000000..220480489da32cd6e7e51eb90c1825e911d44f4f
--- /dev/null
+++ b/test/spass/vector.h
@@ -0,0 +1,188 @@
+/**************************************************************/
+/* ********************************************************** */
+/* *                                                        * */
+/* *             GLOBAL SYSTEM VECTOR                       * */
+/* *                                                        * */
+/* *  $Module:   VECTOR                                     * */ 
+/* *                                                        * */
+/* *  Copyright (C) 1996, 1998, 1999, 2000, 2001            * */
+/* *  MPI fuer Informatik                                   * */
+/* *                                                        * */
+/* *  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.                * */
+/* *                                                        * */
+/* *  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         * */
+/* *                                                        * */
+/* *                                                        * */
+/* $Revision: 21527 $                                        * */
+/* $State$                                            * */
+/* $Date: 2005-04-24 21:10:28 -0700 (Sun, 24 Apr 2005) $                             * */
+/* $Author: duraid $                                       * */
+/* *                                                        * */
+/* *             Contact:                                   * */
+/* *             Christoph Weidenbach                       * */
+/* *             MPI fuer Informatik                        * */
+/* *             Stuhlsatzenhausweg 85                      * */
+/* *             66123 Saarbruecken                         * */
+/* *             Email: weidenb@mpi-sb.mpg.de               * */
+/* *             Germany                                    * */
+/* *                                                        * */
+/* ********************************************************** */
+/**************************************************************/
+
+
+/* $RCSfile$ */
+
+
+#ifndef _VECTOR_
+#define _VECTOR_
+
+#include "misc.h"
+
+
+/**************************************************************/
+/* Type and Variable Definitions                              */
+/**************************************************************/
+
+#define vec_SIZE 10000
+
+typedef POINTER VECTOR[vec_SIZE];
+
+extern VECTOR vec_VECTOR;
+extern int    vec_MAX;
+
+/**************************************************************/
+/* Inline Functions                                           */
+/**************************************************************/
+
+/* Stack operations */
+
+static __inline__ void vec_Init(void)
+{
+  vec_MAX = 0;
+}
+
+static __inline__ void vec_Push(POINTER Value)
+{
+#ifdef CHECK
+  if (vec_MAX >= vec_SIZE) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In vec_Push: Vector Overflow.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  vec_VECTOR[vec_MAX++] = Value;
+}
+
+
+static __inline__ POINTER vec_GetNth(NAT Index)
+{
+#ifdef CHECK
+  if (Index >= vec_SIZE || Index >= vec_MAX) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In vec_GetNth: Illegal vector access.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  return vec_VECTOR[Index];
+}
+
+
+static __inline__ void vec_PutNth(NAT Index, POINTER Value)
+{
+#ifdef CHECK
+  if (Index >= vec_SIZE || Index >= vec_MAX) {
+    misc_StartErrorReport();
+    misc_ErrorReport("\n In vec_PutNth: Illegal vector access.");
+    misc_FinishErrorReport();
+  }
+#endif
+
+  vec_VECTOR[Index] = Value;
+}
+
+
+static __inline__ void vec_Pop(void)
+{
+  --vec_MAX;
+}
+
+static __inline__ POINTER vec_PopResult(void)
+{
+  return vec_VECTOR[--vec_MAX];
+}
+
+static __inline__ void vec_PopToN(int N)
+{
+  vec_VECTOR[N] = vec_VECTOR[--vec_MAX];
+}
+
+static __inline__ void vec_NPop(int N)
+{
+  vec_MAX -= N;
+}
+
+static __inline__ POINTER vec_Top(void)
+{
+  return vec_VECTOR[vec_MAX-1];
+}
+
+static __inline__ POINTER vec_NthTop(int N)
+{
+  return vec_VECTOR[vec_MAX-(1+N)];
+}
+
+
+static __inline__ void vec_RplacTop(POINTER Value)
+{
+  vec_VECTOR[vec_MAX-1] = Value;
+}
+
+static __inline__ void vec_RplacNthTop(int N, POINTER Value)
+{
+  vec_VECTOR[vec_MAX-(1+N)] = Value;
+}
+
+static __inline__ int vec_ActMax(void)
+{
+  return vec_MAX;
+}
+
+static __inline__ void vec_SetMax(int Index)
+{
+  vec_MAX = Index;
+}
+
+static __inline__ BOOL vec_IsMax(int Index)
+{
+  return vec_MAX == Index;
+}
+
+static __inline__ BOOL vec_IsEmpty(void)
+{
+  return vec_MAX == 0;
+}
+
+/**************************************************************/
+/* Prototypes                                                 */
+/**************************************************************/
+
+void vec_Swap(int, int);
+void vec_PrintSel(int, int, void(*)(POINTER));
+void vec_PrintAll(void(*)(POINTER));
+
+#endif