~ubuntu-branches/ubuntu/quantal/spass/quantal

« back to all changes in this revision

Viewing changes to SPASS/rpos.c

  • Committer: Bazaar Package Importer
  • Author(s): Roland Stigge
  • Date: 2010-06-27 18:59:28 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100627185928-kdjuqghv04rxyqmc
Tags: 3.7-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************/
 
2
/* ********************************************************** */
 
3
/* *                                                        * */
 
4
/* *         RECURSIVE PATH ORDERING WITH STATUS            * */
 
5
/* *                                                        * */
 
6
/* *  $Module:   RPOS                                       * */
 
7
/* *                                                        * */
 
8
/* *  Copyright (C) 1997, 1998, 1999, 2000, 2001            * */
 
9
/* *  MPI fuer Informatik                                   * */
 
10
/* *                                                        * */
 
11
/* *  This program is free software; you can redistribute   * */
 
12
/* *  it and/or modify it under the terms of the FreeBSD    * */
 
13
/* *  Licence.                                              * */
 
14
/* *                                                        * */
 
15
/* *  This program is distributed in the hope that it will  * */
 
16
/* *  be useful, but WITHOUT ANY WARRANTY; without even     * */
 
17
/* *  the implied warranty of MERCHANTABILITY or FITNESS    * */
 
18
/* *  FOR A PARTICULAR PURPOSE.  See the LICENCE file       * */
 
19
/* *  for more details.                                     * */
 
20
/* *                                                        * */
 
21
/* *                                                        * */
 
22
/* $Revision: 1.4 $                                         * */
 
23
/* $State: Exp $                                            * */
 
24
/* $Date: 2010-02-22 14:09:59 $                             * */
 
25
/* $Author: weidenb $                                       * */
 
26
/* *                                                        * */
 
27
/* *             Contact:                                   * */
 
28
/* *             Christoph Weidenbach                       * */
 
29
/* *             MPI fuer Informatik                        * */
 
30
/* *             Stuhlsatzenhausweg 85                      * */
 
31
/* *             66123 Saarbruecken                         * */
 
32
/* *             Email: spass@mpi-inf.mpg.de                * */
 
33
/* *             Germany                                    * */
 
34
/* *                                                        * */
 
35
/* ********************************************************** */
 
36
/**************************************************************/
 
37
 
 
38
     
 
39
/* $RCSfile: rpos.c,v $ */
 
40
 
 
41
#include "rpos.h"
 
42
 
 
43
BOOL       rpos_ContEqual(CONTEXT, CONTEXT, TERM, CONTEXT, CONTEXT, TERM);
 
44
ord_RESULT rpos_ContGreaterEqual(CONTEXT, CONTEXT, TERM, CONTEXT, CONTEXT, TERM, BOOL);
 
45
 
 
46
/**************************************************************/
 
47
/* Comparisons                                                */
 
48
/**************************************************************/
 
49
 
 
50
BOOL rpos_Greater(TERM T1, TERM T2, BOOL VarIsConst)
 
51
{
 
52
  return ord_IsGreaterThan(rpos_GreaterEqual(T1, T2, VarIsConst));
 
53
}
 
54
 
 
55
BOOL rpos_ContGreaterAux(CONTEXT GlobalC1, CONTEXT TermC1, TERM T1,
 
56
                         CONTEXT GlobalC2, CONTEXT TermC2, TERM T2,
 
57
                         BOOL VarIsConst)
 
58
{
 
59
  return ord_IsGreaterThan(rpos_ContGreaterEqual(GlobalC1, TermC1, T1, 
 
60
                                                 GlobalC2, TermC2, T2,
 
61
                                                 VarIsConst));
 
62
}
 
63
 
 
64
BOOL rpos_ContGreater(CONTEXT GlobalC1, CONTEXT TermC1, TERM T1,
 
65
                         CONTEXT GlobalC2, CONTEXT TermC2, TERM T2)
 
66
{
 
67
  return ord_IsGreaterThan(rpos_ContGreaterEqual(GlobalC1, TermC1, T1, 
 
68
                                                 GlobalC2, TermC2, T2,
 
69
                                                 FALSE));
 
70
}
 
71
 
 
72
BOOL rpos_ContGreaterSkolemSubst(CONTEXT GlobalC1, CONTEXT TermC1, TERM T1,
 
73
                         CONTEXT GlobalC2, CONTEXT TermC2, TERM T2)
 
74
{
 
75
  return ord_IsGreaterThan(rpos_ContGreaterEqual(GlobalC1, TermC1, T1, 
 
76
                                                 GlobalC2, TermC2, T2,
 
77
                                                 TRUE));
 
78
}
 
79
 
 
80
/**************************************************************/
 
81
/* Top Down Version                                           */
 
82
/**************************************************************/
 
83
 
 
84
static LIST rpos_MultisetDifference(TERM T1, TERM T2)
 
85
/**************************************************************
 
86
  INPUT:   Two terms.
 
87
  RETURNS: The multiset difference between the arguments
 
88
           of both terms with respect to rpos_Equal.
 
89
***************************************************************/
 
90
{
 
91
  LIST result;
 
92
 
 
93
  result = list_Copy(term_ArgumentList(T1));
 
94
  result = list_NMultisetDifference(result, term_ArgumentList(T2),
 
95
                                    (BOOL (*)(POINTER,POINTER)) rpos_Equal);
 
96
  return result;
 
97
}
 
98
  
 
99
  
 
100
static ord_RESULT rpos_MulGreaterEqual(TERM T1, TERM T2, BOOL VarIsConst)
 
101
/**************************************************************
 
102
  INPUT:   Two terms with equal top symbols and multiset status.
 
103
  RETURNS: ord_GREATER_THAN if <T1> is greater than <T2>,
 
104
           ord_EQUAL        if both terms are equal and
 
105
           ord_UNCOMPARABLE otherwise.
 
106
  CAUTION: If <VarIsConst> is set then variables are interpreted as constants
 
107
           with lowest precedence. They are ranked to each other using
 
108
           their variable index.
 
109
***************************************************************/
 
110
{
 
111
  LIST l1, l2;
 
112
 
 
113
  l1 = rpos_MultisetDifference(T1, T2);
 
114
  if (list_Empty(l1))
 
115
    /* If |M| = |N| and M-N = {} then N-M = {} */ 
 
116
    return ord_Equal();   /* Terms are equal */
 
117
  else {
 
118
    LIST scan;
 
119
    BOOL greater;
 
120
 
 
121
    l2 = rpos_MultisetDifference(T2, T1);
 
122
 
 
123
    for (greater = TRUE; !list_Empty(l2) && greater; l2 = list_Pop(l2)) {
 
124
      for (scan = l1, greater = FALSE; !list_Empty(scan) && !greater; scan = list_Cdr(scan))
 
125
        greater = rpos_Greater(list_Car(scan), list_Car(l2), VarIsConst);
 
126
    }
 
127
    list_Delete(l1); /* l2 was freed in the outer for loop */
 
128
    if (greater)
 
129
      return ord_GreaterThan();
 
130
    else
 
131
      return ord_Uncomparable();
 
132
  }
 
133
}
 
134
 
 
135
static ord_RESULT rpos_LexGreaterEqual(TERM T1, TERM T2, BOOL VarIsConst)
 
136
/**************************************************************
 
137
  INPUT:   Two terms with equal top symbols and lexicographic status.
 
138
  RETURNS: ord_GREATER_THAN if <T1> is greater than <T2>,
 
139
           ord_EQUAL        if both terms are equal and 
 
140
           ord_UNCOMPARABLE otherwise.
 
141
  CAUTION: If <VarIsConst> is set then variables are interpreted as constants
 
142
           with lowest precedence. They are ranked to each other using
 
143
           their variable index.
 
144
***************************************************************/
 
145
{
 
146
  ord_RESULT result;
 
147
  LIST       l1, l2, scan1, scan2;
 
148
 
 
149
  if (symbol_HasProperty(term_TopSymbol(T1), ORDRIGHT)) {
 
150
    l1 = list_Reverse(term_ArgumentList(T1)); /* Create new lists */
 
151
    l2 = list_Reverse(term_ArgumentList(T2));
 
152
  } else {
 
153
    l1 = term_ArgumentList(T1);
 
154
    l2 = term_ArgumentList(T2);
 
155
  }
 
156
  /* First ignore equal arguments */
 
157
  result = ord_Equal();
 
158
  for (scan1 = l1, scan2 = l2; !list_Empty(scan1);
 
159
       scan1 = list_Cdr(scan1), scan2 = list_Cdr(scan2)) {
 
160
    result = rpos_GreaterEqual(list_Car(scan1), list_Car(scan2), VarIsConst);
 
161
    if (!ord_IsEqual(result))
 
162
      break;
 
163
  }
 
164
 
 
165
  if (ord_IsEqual(result))  /* All arguments are equal, so the terms */
 
166
    /* empty */;            /* are equal with respect to RPOS */
 
167
  else if (ord_IsGreaterThan(result)) {
 
168
    /* Check if T1 > each remaining argument of T2 */
 
169
    for (scan2 = list_Cdr(scan2); !list_Empty(scan2) && 
 
170
                                rpos_Greater(T1, list_Car(scan2), VarIsConst);
 
171
         scan2 = list_Cdr(scan2)); /* Empty body */
 
172
    if (list_Empty(scan2))
 
173
      result = ord_GreaterThan();
 
174
    else
 
175
      result = ord_Uncomparable();
 
176
  }
 
177
  else {
 
178
    /* Argument of T1 was not >= argument of T2. */
 
179
 
 
180
    /* Try to find an argument of T1 that is >= T2 */
 
181
    for (scan1 = list_Cdr(scan1), result = ord_Uncomparable();
 
182
         !list_Empty(scan1) && !ord_IsGreaterThan(result);
 
183
         scan1 = list_Cdr(scan1)) {
 
184
      if (!ord_IsUncomparable(rpos_GreaterEqual(list_Car(scan1), T2, VarIsConst)))
 
185
        result = ord_GreaterThan();
 
186
    }
 
187
  }
 
188
 
 
189
  if (symbol_HasProperty(term_TopSymbol(T1), ORDRIGHT)) {
 
190
    list_Delete(l1);  /* Delete the lists create above */
 
191
    list_Delete(l2);
 
192
  }
 
193
  return result;
 
194
}
 
195
 
 
196
 
 
197
BOOL rpos_Equal(TERM T1, TERM T2)
 
198
/**************************************************************
 
199
  INPUT:   Two terms.
 
200
  RETURNS: TRUE, if <T1> is equal to <T2> and
 
201
           FALSE otherwise.
 
202
***************************************************************/
 
203
{
 
204
  LIST l1, l2;
 
205
 
 
206
  if (!term_EqualTopSymbols(T1, T2))
 
207
    return FALSE;
 
208
  else if (!term_IsComplex(T1))  /* Equal variable or constant */
 
209
    return TRUE;
 
210
  else {
 
211
    if (symbol_HasProperty(term_TopSymbol(T1), ORDMUL)) {  /* MUL case */
 
212
      l1 = rpos_MultisetDifference(T1, T2);
 
213
      if (list_Empty(l1))
 
214
        return TRUE;
 
215
      else {
 
216
        list_Delete(l1);
 
217
        return FALSE;
 
218
      }
 
219
    } else {   /* LEX case */
 
220
      for (l1 = term_ArgumentList(T1), l2 = term_ArgumentList(T2);
 
221
           !list_Empty(l1) &&  rpos_Equal(list_Car(l1), list_Car(l2));
 
222
           l1 = list_Cdr(l1), l2 = list_Cdr(l2))
 
223
        /* empty */;
 
224
      return list_Empty(l1);  /* All arguments were equal */
 
225
    }
 
226
  }
 
227
}
 
228
 
 
229
 
 
230
ord_RESULT rpos_GreaterEqual(TERM T1, TERM T2, BOOL VarIsConst)
 
231
/**************************************************************
 
232
  INPUT:   Two terms.
 
233
  RETURNS: ord_GREATER_THAN if <T1> is greater than <T2>
 
234
           ord_EQUAL        if both terms are equal
 
235
           ord_UNCOMPARABLE otherwise.
 
236
  CAUTION: The precedence from the order module is used to determine
 
237
           the precedence of symbols!
 
238
           If <VarIsConst> is set then variables are interpreted as constants
 
239
           with lowest precedence. They are ranked to each other using
 
240
           their variable index.
 
241
***************************************************************/
 
242
{
 
243
  LIST scan;
 
244
 
 
245
  if (term_IsVariable(T1)) {
 
246
    if (term_EqualTopSymbols(T1, T2))
 
247
      return ord_Equal();   /* T2 is the same variable */
 
248
    else if(VarIsConst && term_IsVariable(T2)) {
 
249
        if(term_TopSymbol(T1) > term_TopSymbol(T2))
 
250
                return ord_GreaterThan();
 
251
        else
 
252
                return ord_Uncomparable();
 
253
    }
 
254
    else
 
255
      /* A variable can't be greater than another term */
 
256
      return ord_Uncomparable();
 
257
  } else if (!VarIsConst && term_IsVariable(T2)) {   /* T1 isn't a variable */
 
258
    if (term_ContainsSymbol(T1, term_TopSymbol(T2)))
 
259
      return ord_GreaterThan();
 
260
    else
 
261
      return ord_Uncomparable();
 
262
  } else if(VarIsConst && term_IsVariable(T2)){
 
263
      return ord_GreaterThan();    
 
264
  } else if (term_EqualTopSymbols(T1, T2)) {
 
265
    if (symbol_HasProperty(term_TopSymbol(T1), ORDMUL))
 
266
      return rpos_MulGreaterEqual(T1, T2, VarIsConst);
 
267
    else
 
268
      return rpos_LexGreaterEqual(T1, T2, VarIsConst);
 
269
  } else {
 
270
    if (symbol_PrecedenceGreater(ord_PRECEDENCE, term_TopSymbol(T1),
 
271
                                 term_TopSymbol(T2))) {
 
272
      /* Different top symbols, symbol of T1 > symbol of T2. */
 
273
      /* Try if T1 > each argument of T2.                    */
 
274
      for (scan = term_ArgumentList(T2); !list_Empty(scan); scan = list_Cdr(scan))
 
275
        if (!rpos_Greater(T1,  list_Car(scan), VarIsConst))
 
276
          return ord_Uncomparable();
 
277
      return ord_GreaterThan();
 
278
    } else {
 
279
      /* Try to find an argument of T1 that is >= T2 */
 
280
      for (scan = term_ArgumentList(T1); !list_Empty(scan); scan = list_Cdr(scan))
 
281
        if (!ord_IsUncomparable(rpos_GreaterEqual(list_Car(scan), T2, VarIsConst)))
 
282
          return ord_GreaterThan();    /* Argument of T1 >= T2 */
 
283
      return ord_Uncomparable();
 
284
    }
 
285
  }
 
286
}
 
287
 
 
288
ord_RESULT rpos_CompareAux(TERM T1, TERM T2, BOOL VarIsConst)
 
289
/**************************************************************
 
290
  INPUT:   Two terms, a boolean flag indicating if variables
 
291
           of <T1> and <T2> are interpreted as skolem constants
 
292
  RETURNS: The relation between the two terms with respect to the
 
293
           RPOS ordering:
 
294
           ord_GREATER_THAN if <T1> is greater than <T2>,
 
295
           ord_EQUAL        if both terms are equal,
 
296
           ord_SMALLER_THAN if <T2> is greater than <T1> and
 
297
           ord_UNCOMPARABLE otherwise.
 
298
  CAUTION: The precedence from the order module is used to determine
 
299
           the precedence of symbols!
 
300
           If <VarIsConst> is set then variables are interpreted as constants
 
301
           with lowest precedence. They are ranked to each other using
 
302
           their variable index.
 
303
***************************************************************/
 
304
{
 
305
  ord_RESULT result;
 
306
 
 
307
  result = rpos_GreaterEqual(T1, T2, VarIsConst);
 
308
  if (!ord_IsUncomparable(result))
 
309
    return result;
 
310
  else if (rpos_Greater(T2, T1, VarIsConst))
 
311
    return ord_SmallerThan();
 
312
  else
 
313
    return ord_UNCOMPARABLE;
 
314
}
 
315
 
 
316
ord_RESULT rpos_Compare(TERM T1, TERM T2)
 
317
/**************************************************************
 
318
  INPUT:   Two terms.
 
319
  RETURNS: The relation between the two terms with respect to the
 
320
           RPOS ordering:
 
321
           ord_GREATER_THAN if <T1> is greater than <T2>,
 
322
           ord_EQUAL        if both terms are equal,
 
323
           ord_SMALLER_THAN if <T2> is greater than <T1> and
 
324
           ord_UNCOMPARABLE otherwise.
 
325
  CAUTION: The precedence from the order module is used to determine
 
326
           the precedence of symbols!
 
327
***************************************************************/
 
328
{
 
329
    return rpos_CompareAux(T1, T2, FALSE);
 
330
}
 
331
 
 
332
ord_RESULT rpos_CompareSkolem(TERM T1, TERM T2)
 
333
/**************************************************************
 
334
  INPUT:   Two terms.
 
335
  RETURNS: The relation between the two terms with respect to the
 
336
           RPOS ordering:
 
337
           ord_GREATER_THAN if <T1> is greater than <T2>,
 
338
           ord_EQUAL        if both terms are equal,
 
339
           ord_SMALLER_THAN if <T2> is greater than <T1> and
 
340
           ord_UNCOMPARABLE otherwise.
 
341
  CAUTION: The precedence from the order module is used to determine
 
342
           the precedence of symbols! Variables are threated
 
343
           as constants
 
344
***************************************************************/
 
345
{
 
346
    return rpos_CompareAux(T1, T2, TRUE);
 
347
}
 
348
 
 
349
/**************************************************************/
 
350
/* Term comparison with respect to bindings                   */
 
351
/**************************************************************/
 
352
 
 
353
static LIST rpos_ContMultisetDifference(CONTEXT GlobalC1, CONTEXT TermC1, TERM T1, 
 
354
                                        CONTEXT GlobalC2, CONTEXT TermC2, TERM T2)
 
355
/**************************************************************
 
356
  INPUT:      Four contexts and two terms.
 
357
  RETURNS:    The multiset difference between the arguments
 
358
              of both terms with respect to rpos_ContEqual.
 
359
  EFFECT:     Variable bindings are considered.
 
360
  ASSUMPTION: All index variables of <T1> and <T2> are bound in
 
361
              <GlobalC1> and <GlobalCt2>, respectively
 
362
 
 
363
***************************************************************/
 
364
{
 
365
  LIST result, scan1, scan2;
 
366
 
 
367
  /* Don't apply bindings at top level, since that happened */
 
368
  /* in rpos_ContGreaterEqual */
 
369
 
 
370
  /* We can't use list_NMultisetDifference, since that function   */
 
371
  /* expects an equality functions for terms that takes two terms */
 
372
  /* as arguments. We also need the two contexts resolve variable */
 
373
  /* bindings. */
 
374
  result = list_Copy(term_ArgumentList(T1));
 
375
  for (scan2 = term_ArgumentList(T2); !list_Empty(scan2);
 
376
       scan2 = list_Cdr(scan2)) {
 
377
    /* Delete at most one occurrence of the */
 
378
    /* current element of list2 from list1 */
 
379
    for (scan1 = result; !list_Empty(scan1); scan1 = list_Cdr(scan1)) {
 
380
      if (list_Car(scan1) != NULL &&
 
381
          rpos_ContEqual(GlobalC1, TermC1, list_Car(scan1), 
 
382
                         GlobalC2, TermC2, list_Car(scan2))) {
 
383
        /* arg of list1 wasn't deleted earlier and terms are equal */
 
384
        list_Rplaca(scan1, NULL);  /* Mark argument of T1 as deleted */
 
385
        break;
 
386
      }
 
387
    }
 
388
  }
 
389
  return list_PointerDeleteElement(result, NULL); /* Delete all marked terms */
 
390
}
 
391
  
 
392
  
 
393
static ord_RESULT rpos_ContMulGreaterEqual(CONTEXT GlobalC1, CONTEXT TermC1, TERM T1,
 
394
                                           CONTEXT GlobalC2, CONTEXT TermC2, TERM T2,
 
395
                                           BOOL VarIsConst)
 
396
/**************************************************************
 
397
  INPUT:      Two contexts and two terms with equal top symbols
 
398
              and multiset status.
 
399
  RETURNS:      ord_GREATER_THAN if <T1> is greater than <T2>,
 
400
                ord_EQUAL        if both terms are equal and
 
401
                ord_UNCOMPARABLE otherwise.
 
402
  EFFECT:     Variable bindings are considered.
 
403
  ASSUMPTION: All index variables of <T1> and <T2> are bound in
 
404
              <GlobalC1> and <GlobalCt2>, respectively
 
405
***************************************************************/
 
406
{
 
407
  LIST l1, l2;
 
408
 
 
409
  /* Don't apply bindings at top level, since that happened */
 
410
  /* in rpos_ContGreaterEqual. */
 
411
 
 
412
  l1 = rpos_ContMultisetDifference(GlobalC1, TermC1, T1, GlobalC2, TermC2, T2);
 
413
  if (list_Empty(l1))
 
414
    /* If |M| = |N| and M-N = {} then N-M = {} */ 
 
415
    return ord_Equal();   /* Terms are equal */
 
416
  else {
 
417
    LIST scan;
 
418
    BOOL greater;
 
419
 
 
420
    l2 = rpos_ContMultisetDifference(GlobalC2, TermC2, T2, GlobalC1, TermC1, T1);
 
421
 
 
422
    for (greater = TRUE; !list_Empty(l2) && greater; l2 = list_Pop(l2)) {
 
423
      for (scan = l1, greater = FALSE; !list_Empty(scan) && !greater;
 
424
           scan = list_Cdr(scan))
 
425
        greater = rpos_ContGreaterAux(GlobalC1, TermC1, list_Car(scan), 
 
426
                                   GlobalC2, TermC2, list_Car(l2),
 
427
                                   VarIsConst);
 
428
    }
 
429
    list_Delete(l1); /* l2 was freed in the outer for loop */
 
430
    if (greater)
 
431
      return ord_GreaterThan();
 
432
    else
 
433
      return ord_Uncomparable();
 
434
  }
 
435
}
 
436
 
 
437
static ord_RESULT rpos_ContLexGreaterEqual(CONTEXT GlobalC1, CONTEXT TermC1, TERM T1,
 
438
                                           CONTEXT GlobalC2, CONTEXT TermC2, TERM T2,
 
439
                                           BOOL VarIsConst)
 
440
/**************************************************************
 
441
  INPUT:      Two contexts and two terms with equal top symbols
 
442
              and lexicographic status and a flag.
 
443
  RETURNS:      ord_GREATER_THAN if <T1> is greater than <T2>,
 
444
                ord_EQUAL        if both terms are equal and 
 
445
                ord_UNCOMPARABLE otherwise.
 
446
  EFFECT:     Variable bindings are considered.
 
447
  ASSUMPTION: All index variables of <T1> and <T2> are bound in
 
448
              <GlobalC1> and <GlobalCt2>, respectively
 
449
  CAUTION: If <VarIsConst> is set then variables are interpreted as constants
 
450
           with lowest precedence. They are ranked to each other using
 
451
           their variable index.
 
452
***************************************************************/
 
453
{
 
454
  ord_RESULT result;
 
455
  LIST       l1, l2, scan1, scan2;
 
456
 
 
457
  /* Don't apply bindings at top level, since that happened */
 
458
  /* in rpos_ContGreaterEqual */
 
459
 
 
460
  if (symbol_HasProperty(term_TopSymbol(T1), ORDRIGHT)) {
 
461
    l1 = list_Reverse(term_ArgumentList(T1)); /* Create new lists */
 
462
    l2 = list_Reverse(term_ArgumentList(T2));
 
463
  } else {
 
464
    l1 = term_ArgumentList(T1);
 
465
    l2 = term_ArgumentList(T2);
 
466
  }
 
467
  /* First ignore equal arguments */
 
468
  result = ord_Equal();
 
469
  for (scan1 = l1, scan2 = l2; !list_Empty(scan1);
 
470
       scan1 = list_Cdr(scan1), scan2 = list_Cdr(scan2)) {
 
471
    result = rpos_ContGreaterEqual(GlobalC1, TermC1, list_Car(scan1), 
 
472
                                   GlobalC2, TermC2, list_Car(scan2),
 
473
                                   VarIsConst);
 
474
    if (!ord_IsEqual(result))
 
475
      break;
 
476
  }
 
477
 
 
478
  if (ord_IsEqual(result))  /* All arguments are equal, so the terms */
 
479
    /* empty */;            /* are equal with respect to RPOS */
 
480
  else if (ord_IsGreaterThan(result)) {
 
481
    /* Check if T1 > each remaining argument of T2 */
 
482
    for (scan2 = list_Cdr(scan2);
 
483
         !list_Empty(scan2) && rpos_ContGreaterAux(GlobalC1, TermC1, T1, 
 
484
                                                GlobalC2, TermC2, list_Car(scan2),
 
485
                                                VarIsConst);
 
486
         scan2 = list_Cdr(scan2)); /* Empty body */
 
487
    if (list_Empty(scan2))
 
488
      result = ord_GreaterThan();
 
489
    else
 
490
      result = ord_Uncomparable();
 
491
  }
 
492
  else {
 
493
    /* Argument of T1 was not >= argument of T2. */
 
494
    /* Try to find an argument of T1 that is >= T2 */
 
495
    for (scan1 = list_Cdr(scan1), result = ord_Uncomparable();
 
496
         !list_Empty(scan1) && !ord_IsGreaterThan(result);
 
497
         scan1 = list_Cdr(scan1)) {
 
498
      if (!ord_IsUncomparable(rpos_ContGreaterEqual(GlobalC1, TermC1,list_Car(scan1),
 
499
                                                    GlobalC2, TermC2,T2,
 
500
                                                    VarIsConst)))
 
501
        result = ord_GreaterThan();
 
502
    }
 
503
  }
 
504
 
 
505
  if (symbol_HasProperty(term_TopSymbol(T1), ORDRIGHT)) {
 
506
    list_Delete(l1);  /* Delete the lists create above */
 
507
    list_Delete(l2);
 
508
  }
 
509
  return result;
 
510
}
 
511
 
 
512
 
 
513
BOOL rpos_ContEqual(CONTEXT GlobalC1, CONTEXT TermC1, TERM T1, 
 
514
                    CONTEXT GlobalC2, CONTEXT TermC2, TERM T2)
 
515
/**************************************************************
 
516
  INPUT:      Two contexts and two terms.
 
517
  RETURNS:    TRUE, if <T1> is equal to <T2> and
 
518
              FALSE otherwise.
 
519
  EFFECT:     Variable bindings are considered.
 
520
  ASSUMPTION: All index variables of <T1> and <T2> are bound in
 
521
              <GlobalC1> and <GlobalCt2>, respectively
 
522
***************************************************************/
 
523
{
 
524
  LIST l1, l2;
 
525
 
 
526
  T1 = cont_Deref(GlobalC1, &TermC1, T1);
 
527
  T2 = cont_Deref(GlobalC2, &TermC2, T2);
 
528
 
 
529
  if (!term_EqualTopSymbols(T1, T2))
 
530
    return FALSE;
 
531
  else if (!term_IsComplex(T1))
 
532
    return TRUE;
 
533
  else {
 
534
    if (symbol_HasProperty(term_TopSymbol(T1), ORDMUL)) {
 
535
      l1 = rpos_ContMultisetDifference(GlobalC1, TermC1, T1,
 
536
                                       GlobalC2, TermC2, T2);
 
537
      if (list_Empty(l1))
 
538
        return TRUE;
 
539
      else {
 
540
        list_Delete(l1);
 
541
        return FALSE;
 
542
      }
 
543
    } else {   /* LEX case */
 
544
      for (l1 = term_ArgumentList(T1), l2 = term_ArgumentList(T2);
 
545
           !list_Empty(l1) &&  rpos_ContEqual(GlobalC1, TermC1,list_Car(l1),
 
546
                                              GlobalC2, TermC2,list_Car(l2));
 
547
           l1 = list_Cdr(l1), l2 = list_Cdr(l2)); /* empty body */
 
548
      return list_Empty(l1);  /* All arguments were equal */
 
549
    }
 
550
  }
 
551
}
 
552
 
 
553
 
 
554
ord_RESULT rpos_ContGreaterEqual(CONTEXT GlobalC1, CONTEXT TermC1, TERM T1,
 
555
                                 CONTEXT GlobalC2, CONTEXT TermC2, TERM T2,
 
556
                                 BOOL VarIsConst)
 
557
/**************************************************************
 
558
  INPUT:     Two contexts and two terms.
 
559
  RETURNS:      ord_GREATER_THAN if <T1> is greater than <T2>
 
560
                ord_EQUAL        if both terms are equal
 
561
                ord_UNCOMPARABLE otherwise.
 
562
  EFFECT:     Variable bindings are considered.
 
563
  CAUTION:    The precedence from the order module is used to determine
 
564
              the precedence of symbols!
 
565
              If <VarIsConst> is set then variables are interpreted as constants
 
566
              with lowest precedence. They are ranked to each other using
 
567
              their variable index.
 
568
  ASSUMPTION: All index variables of <T1> and <T2> are bound in
 
569
              <GlobalC1> and <GlobalCt2>, respectively
 
570
***************************************************************/
 
571
{
 
572
  LIST scan;
 
573
 
 
574
  T1 = cont_Deref(GlobalC1, &TermC1, T1);
 
575
  T2 = cont_Deref(GlobalC2, &TermC2, T2);
 
576
 
 
577
  if (term_IsVariable(T1)) {
 
578
    if (term_EqualTopSymbols(T1, T2))
 
579
      return ord_Equal();   /* T2 is the same variable */
 
580
    else
 
581
      /* A variable can't be greater than another term */
 
582
      return ord_Uncomparable();
 
583
  } else if (term_IsVariable(T2)) {   /* T1 isn't a variable */
 
584
    if (cont_TermContainsSymbol(GlobalC1, TermC1, T1, term_TopSymbol(T2)))
 
585
      return ord_GreaterThan();
 
586
    else
 
587
      return ord_Uncomparable();
 
588
  } else if (term_EqualTopSymbols(T1, T2)) {
 
589
    if (symbol_HasProperty(term_TopSymbol(T1), ORDMUL))
 
590
      return rpos_ContMulGreaterEqual(GlobalC1, TermC1, T1, 
 
591
                                      GlobalC2, TermC2, T2, VarIsConst);
 
592
    else
 
593
      return rpos_ContLexGreaterEqual(GlobalC1, TermC1, T1, 
 
594
                                      GlobalC2, TermC2, T2, VarIsConst);
 
595
  } else {
 
596
    if (symbol_PrecedenceGreater(ord_PRECEDENCE, term_TopSymbol(T1),
 
597
                                 term_TopSymbol(T2))) {
 
598
      /* Different top symbols, symbol of T1 > symbol of T2. */
 
599
      /* Try if T1 > each argument of T2.                    */
 
600
      for (scan = term_ArgumentList(T2); !list_Empty(scan); scan = list_Cdr(scan))
 
601
        if (!rpos_ContGreaterAux(GlobalC1, TermC1, T1, 
 
602
                              GlobalC2, TermC2, list_Car(scan), VarIsConst))
 
603
          return ord_Uncomparable();
 
604
      return ord_GreaterThan();
 
605
    } else {
 
606
      /* Try to find an argument of T1 that is >= T2 */
 
607
      for (scan = term_ArgumentList(T1); !list_Empty(scan); scan = list_Cdr(scan))
 
608
        if (!ord_IsUncomparable(rpos_ContGreaterEqual(GlobalC1, TermC1,list_Car(scan),
 
609
                                                      GlobalC2, TermC2,T2,
 
610
                                                      VarIsConst)))
 
611
          return ord_GreaterThan();    /* Argument of T1 >= T2 */
 
612
      return ord_Uncomparable();
 
613
    }
 
614
  }
 
615
}
 
616
 
 
617
ord_RESULT rpos_ContCompareAux(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2, BOOL VarIsConst)
 
618
/**************************************************************
 
619
  INPUT:   Two contexts and two terms.
 
620
  RETURNS: The relation between the two terms with respect to the
 
621
           RPOS ordering:
 
622
           ord_GREATER_THAN if <T1> is greater than <T2>,
 
623
           ord_EQUAL        if both terms are equal,
 
624
           ord_SMALLER_THAN if <T2> is greater than <T1> and
 
625
           ord_UNCOMPARABLE otherwise.
 
626
  EFFECT:  Variable bindings are considered.
 
627
           If VarIsConst is true variables are interpreted as constants
 
628
  CAUTION: The precedence from the order module is used to determine
 
629
           the precedence of symbols!
 
630
           If <VarIsConst> is set then variables are interpreted as constants
 
631
           with lowest precedence. They are ranked to each other using
 
632
           their variable index.
 
633
***************************************************************/
 
634
{
 
635
  ord_RESULT result;
 
636
  CONTEXT GlobalC1, GlobalC2;      
 
637
  
 
638
  GlobalC1 = C1;
 
639
  GlobalC2 = C2;
 
640
  
 
641
  T1 = cont_Deref(GlobalC1, &C1, T1);
 
642
  T2 = cont_Deref(GlobalC2, &C2, T2);
 
643
 
 
644
  result = rpos_ContGreaterEqual(GlobalC1, C1, T1, GlobalC2, C2, T2, VarIsConst);
 
645
  if (!ord_IsUncomparable(result))
 
646
    return result;
 
647
  else if (rpos_ContGreaterAux(GlobalC2, C2, T2, GlobalC1, C1, T1, VarIsConst))
 
648
    return ord_SmallerThan();
 
649
  else
 
650
    return ord_UNCOMPARABLE;
 
651
}
 
652
 
 
653
ord_RESULT rpos_ContCompare(CONTEXT C1, TERM T1, CONTEXT C2, TERM T2)
 
654
/**************************************************************
 
655
  INPUT:   Two contexts, two terms and a flag
 
656
  RETURNS: The relation between the two terms with respect to the
 
657
           RPOS ordering:
 
658
           ord_GREATER_THAN if <T1> is greater than <T2>,
 
659
           ord_EQUAL        if both terms are equal,
 
660
           ord_SMALLER_THAN if <T2> is greater than <T1> and
 
661
           ord_UNCOMPARABLE otherwise.
 
662
  EFFECT:  Variable bindings are considered.
 
663
  CAUTION: The precedence from the order module is used to determine
 
664
           the precedence of symbols!
 
665
***************************************************************/
 
666
{
 
667
        return rpos_ContCompareAux(C1, T1, C2, T2, FALSE);
 
668
}