YAP 7.1.0
cmppreds.c
Go to the documentation of this file.
1/*************************************************************************
2* *
3* YAP Prolog *
4* *
5* Yap Prolog was developed at NCCUP - Universidade do Porto *
6* *
7* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
8* *
9**************************************************************************
10* *
11* File: cmppreds.c *
12* Last rev: *
13* mods: *
14* comments: comparing two prolog terms *
15* *
16*************************************************************************/
17
19
52#ifdef SCCS
53static char SccsId[] = "%W% %G%";
54#endif
55
56#include "Yap.h"
57#include "YapHeap.h"
58#include "Yatom.h"
59#include "YapEval.h"
60#if HAVE_STRING_H
61#include <string.h>
62#endif
63#include <wchar.h>
64
65#include "YapError.h"
66
67static Int compare(Term, Term);
68static Int p_compare(USES_REGS1);
69static Int p_acomp(USES_REGS1);
70static Int a_eq(Term, Term);
71static Int a_dif(Term, Term);
72static Int a_gt(Term, Term);
73static Int a_ge(Term, Term);
74static Int a_lt(Term, Term);
75static Int a_le(Term, Term);
76static Int a_noteq(Term, Term);
77static Int a_gen_lt(Term, Term);
78static Int a_gen_le(Term, Term);
79static Int a_gen_gt(Term, Term);
80static Int a_gen_ge(Term, Term);
81
82#define rfloat(X) (X > 0.0 ? 1 : (X == 0.0 ? 0 : -1))
83
84static int cmp_atoms(Atom a1, Atom a2) {
85 return strcmp(RepAtom(a1)->StrOfAE, RepAtom(a2)->StrOfAE);
86}
87
88static Int compare_complex(register CELL *pt0, register CELL *pt0_end,
89 register CELL *pt1) {
90 CACHE_REGS
91 register CELL **to_visit = (CELL **)HR;
92 register Int out = 0;
93
94loop:
95 while (pt0 < pt0_end) {
96 register CELL d0, d1;
97 ++pt0;
98 ++pt1;
99 d0 = Derefa(pt0);
100 d1 = Derefa(pt1);
101 if (IsVarTerm(d0)) {
102 if (IsVarTerm(d1)) {
103 out = Signed(d0) - Signed(d1);
104 if (out)
105 goto done;
106 } else {
107 out = -1;
108 goto done;
109 }
110 } else if (IsVarTerm(d1)) {
111 out = 1;
112 goto done;
113 } else {
114 if (d0 == d1)
115 continue;
116 else if (IsAtomTerm(d0)) {
117 if (IsAtomTerm(d1))
118 out = cmp_atoms(AtomOfTerm(d0), AtomOfTerm(d1));
119 else if (IsPrimitiveTerm(d1))
120 out = 1;
121 else
122 out = -1;
123 /* I know out must be != 0 */
124 goto done;
125 } else if (IsIntTerm(d0)) {
126 if (IsIntTerm(d1))
127 out = IntOfTerm(d0) - IntOfTerm(d1);
128 else if (IsFloatTerm(d1)) {
129 out = 1;
130 } else if (IsLongIntTerm(d1)) {
131 out = IntOfTerm(d0) - LongIntOfTerm(d1);
132#ifdef USE_GMP
133 } else if (IsBigIntTerm(d1)) {
134 out = Yap_gmp_tcmp_int_big(IntOfTerm(d0), d1);
135#endif
136 } else
137 out = 1;
138 if (out != 0)
139 goto done;
140 } else if (IsFloatTerm(d0)) {
141 if (IsFloatTerm(d1)) {
142 out = rfloat(FloatOfTerm(d0) - FloatOfTerm(d1));
143 } else if (IsRefTerm(d1)) {
144 out = 1;
145 } else {
146 out = -1;
147 };
148 if (out != 0)
149 goto done;
150 } else if (IsStringTerm(d0)) {
151 if (IsStringTerm(d1)) {
152 out = strcmp((char *)StringOfTerm(d0), (char *)StringOfTerm(d1));
153 } else if (IsIntTerm(d1))
154 out = 1;
155 else if (IsFloatTerm(d1)) {
156 out = 1;
157 } else if (IsLongIntTerm(d1)) {
158 out = 1;
159#ifdef USE_GMP
160 } else if (IsBigIntTerm(d1)) {
161 out = 1;
162#endif
163 } else if (IsRefTerm(d1)) {
164 out = 1;
165 } else {
166 out = -1;
167 }
168 if (out != 0)
169 goto done;
170 } else if (IsLongIntTerm(d0)) {
171 if (IsIntTerm(d1))
172 out = LongIntOfTerm(d0) - IntOfTerm(d1);
173 else if (IsFloatTerm(d1)) {
174 out = 1;
175 } else if (IsLongIntTerm(d1)) {
176 out = LongIntOfTerm(d0) - LongIntOfTerm(d1);
177#ifdef USE_GMP
178 } else if (IsBigIntTerm(d1)) {
179 out = Yap_gmp_tcmp_int_big(LongIntOfTerm(d0), d1);
180#endif
181 } else if (IsRefTerm(d1)) {
182 out = 1;
183 } else {
184 out = -1;
185 }
186 if (out != 0)
187 goto done;
188 }
189#ifdef USE_GMP
190 else if (IsBigIntTerm(d0)) {
191 if (IsIntTerm(d1)) {
192 out = Yap_gmp_tcmp_big_int(d0, IntOfTerm(d1));
193 } else if (IsFloatTerm(d1)) {
194 out = 1;
195 } else if (IsLongIntTerm(d1)) {
196 out = Yap_gmp_tcmp_big_int(d0, LongIntOfTerm(d1));
197 } else if (IsBigIntTerm(d1)) {
198 out = Yap_gmp_tcmp_big_big(d0, d1);
199 } else if (IsRefTerm(d1))
200 out = 1;
201 else
202 out = -1;
203 if (out != 0)
204 return out;
205 } else if (IsPairTerm(d0)) {
206 if (!IsPairTerm(d1)) {
207 if (IsApplTerm(d1)) {
208 Functor f = FunctorOfTerm(d1);
209 if (IsExtensionFunctor(f))
210 out = 1;
211 else if (!(out = 2 - ArityOfFunctor(f)))
212 out = strcmp(".", (char *)RepAtom(NameOfFunctor(f))->StrOfAE);
213 } else
214 out = 1;
215 goto done;
216 }
217#ifdef RATIONAL_TREES
218 to_visit[0] = pt0;
219 to_visit[1] = pt0_end;
220 to_visit[2] = pt1;
221 to_visit[3] = (CELL *)*pt0;
222 to_visit += 4;
223 *pt0 = d1;
224#else
225 /* store the terms to visit */
226 if (pt0 < pt0_end) {
227 to_visit[0] = pt0;
228 to_visit[1] = pt0_end;
229 to_visit[2] = pt1;
230 to_visit += 3;
231 }
232#endif
233 pt0 = RepPair(d0) - 1;
234 pt0_end = RepPair(d0) + 1;
235 pt1 = RepPair(d1) - 1;
236 continue;
237 } else if (IsRefTerm(d0)) {
238 if (IsRefTerm(d1))
239 out = Unsigned(RefOfTerm(d1)) - Unsigned(RefOfTerm(d0));
240 else
241 out = -1;
242 goto done;
243 } else if (IsApplTerm(d0)) {
244 register Functor f;
245 register CELL *ap2, *ap3;
246 if (!IsApplTerm(d1)) {
247 out = 1;
248 goto done;
249 } else {
250 /* store the terms to visit */
251 Functor f2;
252 ap2 = RepAppl(d0);
253 ap3 = RepAppl(d1);
254 f = (Functor)(*ap2);
255 if (IsExtensionFunctor(f)) {
256 out = 1;
257 goto done;
258 }
259 f2 = (Functor)(*ap3);
260 if (IsExtensionFunctor(f2)) {
261 out = -1;
262 goto done;
263 }
264 /* compare functors */
265 if (f != (Functor)*ap3) {
266 if (!(out = ArityOfFunctor(f) - ArityOfFunctor(f2)))
267 out = cmp_atoms(NameOfFunctor(f), NameOfFunctor(f2));
268 goto done;
269 }
270#ifdef RATIONAL_TREES
271 to_visit[0] = pt0;
272 to_visit[1] = pt0_end;
273 to_visit[2] = pt1;
274 to_visit[3] = (CELL *)*pt0;
275 to_visit += 4;
276 *pt0 = d1;
277#else
278 /* store the terms to visit */
279 if (pt0 < pt0_end) {
280 to_visit[0] = pt0;
281 to_visit[1] = pt0_end;
282 to_visit[2] = pt1;
283 to_visit += 3;
284 }
285#endif
286 d0 = ArityOfFunctor(f);
287 pt0 = ap2;
288 pt0_end = ap2 + d0;
289 pt1 = ap3;
290 continue;
291 }
292 }
293 }
294 }
295 /* Do we still have compound terms to visit */
296 if (to_visit > (CELL **)HR) {
297#ifdef RATIONAL_TREES
298 to_visit -= 4;
299 pt0 = to_visit[0];
300 pt0_end = to_visit[1];
301 pt1 = to_visit[2];
302 *pt0 = (CELL)to_visit[3];
303#else
304 to_visit -= 3;
305 pt0 = to_visit[0];
306 pt0_end = to_visit[1];
307 pt1 = to_visit[2];
308#endif
309 goto loop;
310 }
311
312 done:
313/* failure */
314 while (to_visit > (CELL **)HR) {
315 to_visit -= 4;
316 pt0 = to_visit[0];
317 pt0_end = to_visit[1];
318 pt1 = to_visit[2];
319 *pt0 = (CELL)to_visit[3];
320 }
321#endif
322 return (out);
323}
324
325inline static Int compare(Term t1, Term t2) /* compare terms t1 and t2 */
326{
327
328 if (t1 == t2)
329 return 0;
330 if (IsVarTerm(t1)) {
331 if (IsVarTerm(t2))
332 return Signed(t1) - Signed(t2);
333 return -1;
334 } else if (IsVarTerm(t2)) {
335 /* get rid of variables */
336 return 1;
337 }
338 if (IsAtomOrIntTerm(t1)) {
339 if (IsAtomTerm(t1)) {
340 if (IsAtomTerm(t2))
341 return cmp_atoms(AtomOfTerm(t1), AtomOfTerm(t2));
342 if (IsPrimitiveTerm(t2))
343 return 1;
344 if (IsStringTerm(t2))
345 return 1;
346 return -1;
347 } else {
348 if (IsIntTerm(t2)) {
349 return IntOfTerm(t1) - IntOfTerm(t2);
350 }
351 if (IsApplTerm(t2)) {
352 Functor fun2 = FunctorOfTerm(t2);
353 switch ((CELL)fun2) {
354 case double_e:
355 return 1;
356 case long_int_e:
357 return IntOfTerm(t1) - LongIntOfTerm(t2);
358#ifdef USE_GMP
359 case big_int_e:
360 return Yap_gmp_tcmp_int_big(IntOfTerm(t1), t2);
361#endif
362 case db_ref_e:
363 return 1;
364 case string_e:
365 return -1;
366 }
367 }
368 return -1;
369 }
370 } else if (IsPairTerm(t1)) {
371 if (IsApplTerm(t2)) {
372 Functor f = FunctorOfTerm(t2);
373 if (IsExtensionFunctor(f))
374 return 1;
375 else {
376 if (f != FunctorDot)
377 return strcmp(".", RepAtom(NameOfFunctor(f))->StrOfAE);
378 else {
379 return compare_complex(RepPair(t1) - 1, RepPair(t1) + 1, RepAppl(t2));
380 }
381 }
382 }
383 if (IsPairTerm(t2)) {
384 return (
385 compare_complex(RepPair(t1) - 1, RepPair(t1) + 1, RepPair(t2) - 1));
386 } else
387 return 1;
388 } else {
389 /* compound term */
390 Functor fun1 = FunctorOfTerm(t1);
391
392 if (IsExtensionFunctor(fun1)) {
393 /* float, long, big, dbref */
394 switch ((CELL)fun1) {
395 case double_e: {
396 if (IsFloatTerm(t2))
397 return (rfloat(FloatOfTerm(t1) - FloatOfTerm(t2)));
398 if (IsRefTerm(t2))
399 return 1;
400 return -1;
401 }
402 case long_int_e: {
403 if (IsIntTerm(t2))
404 return LongIntOfTerm(t1) - IntOfTerm(t2);
405 if (IsFloatTerm(t2)) {
406 return 1;
407 }
408 if (IsLongIntTerm(t2))
409 return LongIntOfTerm(t1) - LongIntOfTerm(t2);
410#ifdef USE_GMP
411 if (IsBigIntTerm(t2)) {
412 return Yap_gmp_tcmp_int_big(LongIntOfTerm(t1), t2);
413 }
414#endif
415 if (IsRefTerm(t2))
416 return 1;
417 return -1;
418 }
419#ifdef USE_GMP
420 case big_int_e: {
421 if (IsIntTerm(t2))
422 return Yap_gmp_tcmp_big_int(t1, IntOfTerm(t2));
423 if (IsFloatTerm(t2)) {
424 return 1;
425 }
426 if (IsLongIntTerm(t2))
427 return Yap_gmp_tcmp_big_int(t1, LongIntOfTerm(t2));
428 if (IsBigIntTerm(t2)) {
429 return Yap_gmp_tcmp_big_big(t1, t2);
430 }
431 if (IsRefTerm(t2))
432 return 1;
433 return -1;
434 }
435#endif
436 case string_e: {
437 if (IsApplTerm(t2)) {
438 Functor fun2 = FunctorOfTerm(t2);
439 switch ((CELL)fun2) {
440 case double_e:
441 return 1;
442 case long_int_e:
443 return 1;
444#ifdef USE_GMP
445 case big_int_e:
446 return 1;
447#endif
448 case db_ref_e:
449 return 1;
450 case string_e:
451 return strcmp((char *)StringOfTerm(t1), (char *)StringOfTerm(t2));
452 }
453 return -1;
454 }
455 return -1;
456 }
457 case db_ref_e:
458 if (IsRefTerm(t2))
459 return Unsigned(RefOfTerm(t2)) - Unsigned(RefOfTerm(t1));
460 return -1;
461 }
462 }
463 if (!IsApplTerm(t2)) {
464 if (IsPairTerm(t2)) {
465 Int out;
466 Functor f = FunctorOfTerm(t1);
467
468 if (!(out = ArityOfFunctor(f)) - 2)
469 out = strcmp((char *)RepAtom(NameOfFunctor(f))->StrOfAE, ".");
470 return out;
471 }
472 return 1;
473 } else {
474 Functor fun2 = FunctorOfTerm(t2);
475 Int r;
476
477 if (IsExtensionFunctor(fun2)) {
478 return 1;
479 }
480 r = ArityOfFunctor(fun1) - ArityOfFunctor(fun2);
481 if (r)
482 return r;
483 r = cmp_atoms(NameOfFunctor(fun1), NameOfFunctor(fun2));
484 if (r)
485 return r;
486 else
487 return (compare_complex(RepAppl(t1), RepAppl(t1) + ArityOfFunctor(fun1),
488 RepAppl(t2)));
489 }
490 }
491}
492
493Int Yap_compare_terms(Term d0, Term d1) {
494 return compare(Deref(d0), Deref(d1));
495}
496
511Int p_compare(USES_REGS1) { /* compare(?Op,?T1,?T2) */
512 Int r = compare(Deref(ARG2), Deref(ARG3));
513 Atom p;
514 Term t = Deref(ARG1);
515 if (r < 0)
516 p = AtomLT;
517 else if (r > 0)
518 p = AtomGT;
519 else
520 p = AtomEQ;
521 if (!IsVarTerm(t)) {
522 if (IsAtomTerm(t)) {
523 Atom a = AtomOfTerm(t);
524 if (a == p)
525 return true;
526 if (a != AtomLT && a != AtomGT && a != AtomEq)
527 Yap_Error(DOMAIN_ERROR_ORDER, ARG1, NULL);
528 } else {
529 Yap_Error(TYPE_ERROR_ATOM, ARG1, NULL);
530 }
531 return false;
532 }
533
534 return Yap_unify_constant(ARG1, MkAtomTerm(p));
535}
536
541static Int a_noteq(Term t1, Term t2) { return (compare(t1, t2) != 0); }
542
543static Int a_gen_lt(Term t1, Term t2) { return (compare(t1, t2) < 0); }
544
551static Int a_gen_le(Term t1, Term t2) { return (compare(t1, t2) <= 0); }
552
558static Int a_gen_gt(Term t1, Term t2) { return compare(t1, t2) > 0; }
559
564static Int a_gen_ge(Term t1, Term t2) { return compare(t1, t2) >= 0; }
565
580inline static Int int_cmp(Int dif) { return dif; }
581
582inline static Int flt_cmp(Float dif) {
583 if (dif < 0.0)
584 return -1;
585 if (dif > 0.0)
586 return 1;
587 return dif = 0.0;
588}
589
590static Int a_cmp(Term t1, Term t2 USES_REGS) {
591 if (IsVarTerm(t1)) {
592 Yap_ArithError(INSTANTIATION_ERROR, t1,
593 "while doing arithmetic comparison");
594 }
595 if (IsVarTerm(t2)) {
596 Yap_ArithError(INSTANTIATION_ERROR, t2,
597 "while doing arithmetic comparison");
598 }
599 if (IsFloatTerm(t1) && IsFloatTerm(t2)) {
600 return flt_cmp(FloatOfTerm(t1) - FloatOfTerm(t2));
601 }
602 if (IsIntegerTerm(t1) && IsIntegerTerm(t2)) {
603 return int_cmp(IntegerOfTerm(t1) - IntegerOfTerm(t2));
604 }
605 t1 = Yap_Eval(t1);
606 if (!t1) {
607 return FALSE;
608 }
609 if (IsIntegerTerm(t1)) {
610 Int i1 = IntegerOfTerm(t1);
611 t2 = Yap_Eval(t2);
612
613 if (IsIntegerTerm(t2)) {
614 Int i2 = IntegerOfTerm(t2);
615 return int_cmp(i1 - i2);
616 } else if (IsFloatTerm(t2)) {
617 Float f2 = FloatOfTerm(t2);
618#if HAVE_ISNAN
619 if (isnan(f2)) {
620 Yap_ArithError(EVALUATION_ERROR_UNDEFINED, t2,
621 "trying to evaluate nan");
622 }
623#endif
624 return flt_cmp(i1 - f2);
625#ifdef USE_GMP
626 } else if (IsBigIntTerm(t2)) {
627 return Yap_gmp_cmp_int_big(i1, t2);
628#endif
629 } else {
630 return FALSE;
631 }
632 } else if (IsFloatTerm(t1)) {
633 Float f1 = FloatOfTerm(t1);
634#if HAVE_ISNAN
635 if (isnan(f1)) {
636 Yap_ArithError(EVALUATION_ERROR_UNDEFINED, t1,
637 "trying to evaluate nan");
638 }
639#endif
640 t2 = Yap_Eval(t2);
641#if HAVE_ISNAN
642 if (isnan(f1))
643 return -1;
644#endif
645
646 if (IsIntegerTerm(t2)) {
647 Int i2 = IntegerOfTerm(t2);
648 return flt_cmp(f1 - i2);
649 } else if (IsFloatTerm(t2)) {
650 Float f2 = FloatOfTerm(t2);
651#if HAVE_ISNAN
652 if (isnan(f2)) {
653 Yap_ArithError(EVALUATION_ERROR_UNDEFINED, t2,
654 "trying to evaluate nan");
655 }
656#endif
657 return flt_cmp(f1 - f2);
658#ifdef USE_GMP
659 } else if (IsBigIntTerm(t2)) {
660 return Yap_gmp_cmp_float_big(f1, t2);
661#endif
662 } else {
663 return FALSE;
664 }
665#ifdef USE_GMP
666 } else if (IsBigIntTerm(t1)) {
667 {
668 t2 = Yap_Eval(t2);
669
670 if (IsIntegerTerm(t2)) {
671 return Yap_gmp_cmp_big_int(t1, IntegerOfTerm(t2));
672 } else if (IsFloatTerm(t2)) {
673 Float f2 = FloatOfTerm(t2);
674#if HAVE_ISNAN
675 if (isnan(f2)) {
676 Yap_ArithError(EVALUATION_ERROR_UNDEFINED, t2,
677 "trying to evaluate nan");
678 }
679#endif
680 return Yap_gmp_cmp_big_float(t1, f2);
681 } else if (IsBigIntTerm(t2)) {
682 return Yap_gmp_cmp_big_big(t1, t2);
683 } else {
684 return FALSE;
685 }
686 }
687#endif
688 } else {
689 return FALSE;
690 }
691}
692
693Int Yap_acmp(Term t1, Term t2 USES_REGS) {
694 Int out = a_cmp(t1, t2 PASS_REGS);
695 return out;
696}
697
698static Int p_acomp(USES_REGS1) { /* $a_compare(?R,+X,+Y) */
699 Term t1 = Deref(ARG1);
700 Term t2 = Deref(ARG2);
701 Int out;
702
703 out = a_cmp(t1, t2 PASS_REGS);
704 return out;
705}
706
713static Int a_eq(Term t1, Term t2) {
714 CACHE_REGS
715 /* A =:= B */
716 Int out;
717 t1 = Deref(t1);
718 t2 = Deref(t2);
719
720 if (IsVarTerm(t1)) {
721 Yap_Error(INSTANTIATION_ERROR, t1, "=:=/2");
722 return (FALSE);
723 }
724 if (IsVarTerm(t2)) {
725 Yap_Error(INSTANTIATION_ERROR, t2, "=:=/2");
726 return (FALSE);
727 }
728 if (IsFloatTerm(t1)) {
729 if (IsFloatTerm(t2))
730 return (FloatOfTerm(t1) == FloatOfTerm(t2));
731 else if (IsIntegerTerm(t2)) {
732 return (FloatOfTerm(t1) == IntegerOfTerm(t2));
733 }
734 }
735 if (IsIntegerTerm(t1)) {
736 if (IsIntegerTerm(t2)) {
737 return (IntegerOfTerm(t1) == IntegerOfTerm(t2));
738 } else if (IsFloatTerm(t2)) {
739 return (FloatOfTerm(t2) == IntegerOfTerm(t1));
740 }
741 }
742 out = a_cmp(t1, t2 PASS_REGS);
743 return out == 0;
744}
745
746/*
747 @pred +_X_ =\\= _Y_ is iso
748 Difference of arithmetic expressions
749
750 The value of the expression _X_ is different from the value of expression
751 _Y_.
752 */
753static Int a_dif(Term t1, Term t2) {
754 CACHE_REGS
755 Int out = a_cmp(Deref(t1), Deref(t2) PASS_REGS);
756 return out != 0;
757}
758
766static Int a_gt(Term t1, Term t2) { /* A > B */
767 CACHE_REGS
768 Int out = a_cmp(Deref(t1), Deref(t2) PASS_REGS);
769 return out > 0;
770}
771
779static Int a_ge(Term t1, Term t2) { /* A >= B */
780 CACHE_REGS
781 Int out = a_cmp(Deref(t1), Deref(t2) PASS_REGS);
782 return out >= 0;
783}
784
792static Int a_lt(Term t1, Term t2) { /* A < B */
793 CACHE_REGS
794 Int out = a_cmp(Deref(t1), Deref(t2) PASS_REGS);
795 return out < 0;
796}
797
807static Int a_le(Term t1, Term t2) { /* A <= B */
808 CACHE_REGS
809 Int out = a_cmp(Deref(t1), Deref(t2) PASS_REGS);
810 return out <= 0;
811}
812
817void Yap_InitCmpPreds(void) {
818 Yap_InitCmpPred("=:=", 2, a_eq, SafePredFlag | BinaryPredFlag);
819 Yap_InitCmpPred("=\\=", 2, a_dif, SafePredFlag | BinaryPredFlag);
820 Yap_InitCmpPred(">", 2, a_gt, SafePredFlag | BinaryPredFlag);
821 Yap_InitCmpPred("=<", 2, a_le, SafePredFlag | BinaryPredFlag);
822 Yap_InitCmpPred("<", 2, a_lt, SafePredFlag | BinaryPredFlag);
823 Yap_InitCmpPred(">=", 2, a_ge, SafePredFlag | BinaryPredFlag);
824 Yap_InitCPred("$a_compare", 3, p_acomp, TestPredFlag | SafePredFlag);
825 Yap_InitCmpPred("\\==", 2, a_noteq, BinaryPredFlag | SafePredFlag);
826 Yap_InitCmpPred("@<", 2, a_gen_lt, BinaryPredFlag | SafePredFlag);
827 Yap_InitCmpPred("@=<", 2, a_gen_le, BinaryPredFlag | SafePredFlag);
828 Yap_InitCmpPred("@>", 2, a_gen_gt, BinaryPredFlag | SafePredFlag);
829 Yap_InitCmpPred("@>=", 2, a_gen_ge, BinaryPredFlag | SafePredFlag);
830 Yap_InitCPred("compare", 3, p_compare, TestPredFlag | SafePredFlag);
831}
832
Main definitions.