| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | /*************************************************************************
 | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |  *									 * | 
					
						
							|  |  |  |  *	 YAP Prolog 							 * | 
					
						
							|  |  |  |  *									 * | 
					
						
							|  |  |  |  *	Yap Prolog was developed at NCCUP - Universidade do Porto	 * | 
					
						
							|  |  |  |  *									 * | 
					
						
							|  |  |  |  * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997	 * | 
					
						
							|  |  |  |  *									 * | 
					
						
							|  |  |  |  ************************************************************************** | 
					
						
							|  |  |  |  *									 * | 
					
						
							|  |  |  |  * File:		arith2.c						 * | 
					
						
							|  |  |  |  * Last rev:								 * | 
					
						
							|  |  |  |  * mods:									 * | 
					
						
							|  |  |  |  * comments:	arithmetical expression evaluation			 * | 
					
						
							|  |  |  |  *									 * | 
					
						
							|  |  |  |  *************************************************************************/ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef SCCS
 | 
					
						
							|  |  |  | static char     SccsId[] = "%W% %G%"; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * This file implements unary arithmetic operations in YAP | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "Yap.h"
 | 
					
						
							|  |  |  | #include "Yatom.h"
 | 
					
						
							| 
									
										
										
										
											2009-10-23 14:22:17 +01:00
										 |  |  | #include "YapHeap.h"
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #include "eval.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | #include "arith2.h"
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | typedef struct init_un_eval { | 
					
						
							|  |  |  |   char          *OpName; | 
					
						
							|  |  |  |   arith2_op      f; | 
					
						
							|  |  |  | } InitBinEntry; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | static Term | 
					
						
							|  |  |  | p_mod(Term t1, Term t2) { | 
					
						
							|  |  |  |   switch (ETypeOfTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   case (CELL)long_int_e: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case (CELL)long_int_e: | 
					
						
							|  |  |  |       /* two integers */ | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  | 	Int i1 = IntegerOfTerm(t1); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	Int i2 = IntegerOfTerm(t2); | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  | 	Int mod; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-22 14:48:33 +01:00
										 |  |  | 	if (i2 == 0) | 
					
						
							|  |  |  | 	  return Yap_ArithError(EVALUATION_ERROR_ZERO_DIVISOR, t2, "X is " Int_FORMAT " mod 0", i1); | 
					
						
							| 
									
										
										
										
											2009-02-09 21:56:40 +00:00
										 |  |  | 	if (i1 == Int_MIN && i2 == -1) { | 
					
						
							| 
									
										
										
										
											2009-04-26 10:46:00 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2009-02-09 21:56:40 +00:00
										 |  |  | 	  return Yap_gmp_add_ints(Int_MAX, 1);	   | 
					
						
							| 
									
										
										
										
											2009-04-26 10:46:00 -05:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  | 	  return Yap_ArithError(EVALUATION_ERROR_INT_OVERFLOW, t1, | 
					
						
							| 
									
										
										
										
											2009-04-26 10:46:00 -05:00
										 |  |  | 		    "// /2 with %d and %d", i1, i2); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-02-09 21:56:40 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  | 	mod = i1%i2; | 
					
						
							|  |  |  | 	if (mod && (mod ^ i2) < 0) | 
					
						
							|  |  |  | 	  mod += i2; | 
					
						
							|  |  |  | 	RINT(mod); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     case (CELL)double_e: | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  |       return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "mod/2"); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case (CELL)big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return Yap_gmp_mod_int_big(IntegerOfTerm(t1), t2); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |       RERROR(); | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   case (CELL)double_e: | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  |     return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "mod/2"); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   case (CELL)big_int_e: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							|  |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case long_int_e: | 
					
						
							|  |  |  |       /* modulo between bignum and integer */ | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Int i2 = IntegerOfTerm(t2); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-22 14:48:33 +01:00
										 |  |  | 	if (i2 == 0) | 
					
						
							|  |  |  | 	  return Yap_ArithError(EVALUATION_ERROR_ZERO_DIVISOR, t2, "X is ... mod 0"); | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  | 	return Yap_gmp_mod_big_int(t1, i2); | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     case (CELL)big_int_e: | 
					
						
							|  |  |  |       /* two bignums */ | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return Yap_gmp_mod_big_big(t1, t2); | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |     case double_e: | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  |       return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "mod/2"); | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |       RERROR(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2006-01-02 23:19:10 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |   default: | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |     RERROR(); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-30 21:50:33 -05:00
										 |  |  | static Term | 
					
						
							|  |  |  | p_div2(Term t1, Term t2) { | 
					
						
							|  |  |  |   switch (ETypeOfTerm(t1)) { | 
					
						
							|  |  |  |   case (CELL)long_int_e: | 
					
						
							|  |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							|  |  |  |     case (CELL)long_int_e: | 
					
						
							|  |  |  |       /* two integers */ | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Int i1 = IntegerOfTerm(t1); | 
					
						
							|  |  |  | 	Int i2 = IntegerOfTerm(t2); | 
					
						
							| 
									
										
										
										
											2010-10-08 10:58:08 +01:00
										 |  |  | 	Int res, mod; | 
					
						
							| 
									
										
										
										
											2010-08-30 21:50:33 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-22 14:48:33 +01:00
										 |  |  | 	if (i2 == 0) | 
					
						
							|  |  |  | 	  return Yap_ArithError(EVALUATION_ERROR_ZERO_DIVISOR, t2, "X is " Int_FORMAT " div 0", i1); | 
					
						
							| 
									
										
										
										
											2010-08-30 21:50:33 -05:00
										 |  |  | 	if (i1 == Int_MIN && i2 == -1) { | 
					
						
							|  |  |  | #ifdef USE_GMP
 | 
					
						
							|  |  |  | 	  return Yap_gmp_add_ints(Int_MAX, 1);	   | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	  return Yap_ArithError(EVALUATION_ERROR_INT_OVERFLOW, t1, | 
					
						
							|  |  |  | 		    "// /2 with %d and %d", i1, i2); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-10-08 10:58:08 +01:00
										 |  |  | 	mod = i1%i2; | 
					
						
							|  |  |  | 	if (mod && (mod ^ i2) < 0) | 
					
						
							|  |  |  | 	  mod += i2; | 
					
						
							|  |  |  | 	res = (i1 - mod) / i2; | 
					
						
							| 
									
										
										
										
											2010-08-30 21:50:33 -05:00
										 |  |  | 	RINT(res); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     case (CELL)double_e: | 
					
						
							|  |  |  |       return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "div/2"); | 
					
						
							|  |  |  |     case (CELL)big_int_e: | 
					
						
							|  |  |  | #ifdef USE_GMP
 | 
					
						
							|  |  |  |       return Yap_gmp_div_int_big(IntegerOfTerm(t1), t2); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       RERROR(); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   case (CELL)double_e: | 
					
						
							|  |  |  |     return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "div/2"); | 
					
						
							|  |  |  |   case (CELL)big_int_e: | 
					
						
							|  |  |  | #ifdef USE_GMP
 | 
					
						
							|  |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							|  |  |  |     case long_int_e: | 
					
						
							|  |  |  |       /* modulo between bignum and integer */ | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Int i2 = IntegerOfTerm(t2); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-22 14:48:33 +01:00
										 |  |  | 	if (i2 == 0) | 
					
						
							|  |  |  | 	  return Yap_ArithError(EVALUATION_ERROR_ZERO_DIVISOR, t2, "X is ... div 0"); | 
					
						
							| 
									
										
										
										
											2010-08-30 21:50:33 -05:00
										 |  |  | 	return Yap_gmp_div2_big_int(t1, i2); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     case (CELL)big_int_e: | 
					
						
							|  |  |  |       /* two bignums */ | 
					
						
							|  |  |  |       return Yap_gmp_div2_big_big(t1, t2); | 
					
						
							|  |  |  |     case double_e: | 
					
						
							|  |  |  |       return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "mod/2"); | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       RERROR(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   default: | 
					
						
							|  |  |  |     RERROR(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | static Term | 
					
						
							|  |  |  | p_rem(Term t1, Term t2) { | 
					
						
							|  |  |  |   switch (ETypeOfTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |   case (CELL)long_int_e: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |     case (CELL)long_int_e: | 
					
						
							|  |  |  |       /* two integers */ | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Int i1 = IntegerOfTerm(t1); | 
					
						
							|  |  |  | 	Int i2 = IntegerOfTerm(t2); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-22 14:48:33 +01:00
										 |  |  | 	if (i2 == 0) | 
					
						
							|  |  |  | 	  return Yap_ArithError(EVALUATION_ERROR_ZERO_DIVISOR, t2, "X is " Int_FORMAT " rem 0", i1); | 
					
						
							| 
									
										
										
										
											2009-02-09 21:56:40 +00:00
										 |  |  | 	if (i1 == Int_MIN && i2 == -1) { | 
					
						
							| 
									
										
										
										
											2009-04-26 10:46:00 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2009-02-09 21:56:40 +00:00
										 |  |  | 	  return Yap_gmp_add_ints(Int_MAX, 1);	   | 
					
						
							| 
									
										
										
										
											2009-04-26 10:46:00 -05:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  | 	  return Yap_ArithError(EVALUATION_ERROR_INT_OVERFLOW, t1, | 
					
						
							| 
									
										
										
										
											2009-04-26 10:46:00 -05:00
										 |  |  | 		    "rem/2 with %d and %d", i1, i2); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-02-09 21:56:40 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  | 	RINT(i1%i2); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     case (CELL)double_e: | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  |       return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "mod/2"); | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |     case (CELL)big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return Yap_gmp_rem_int_big(IntegerOfTerm(t1), t2); | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |       RERROR(); | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case (CELL)double_e: | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  |     return Yap_ArithError(TYPE_ERROR_INTEGER, t1, "mod/2"); | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |   case (CELL)big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |     case long_int_e: | 
					
						
							| 
									
										
										
										
											2011-04-22 14:48:33 +01:00
										 |  |  |       if (IntegerOfTerm(t2) == 0) | 
					
						
							|  |  |  | 	return Yap_ArithError(EVALUATION_ERROR_ZERO_DIVISOR, t2, "X is ... rem 0"); | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return Yap_gmp_rem_big_int(t1, IntegerOfTerm(t2)); | 
					
						
							|  |  |  |     case (CELL)big_int_e: | 
					
						
							|  |  |  |       /* two bignums */ | 
					
						
							|  |  |  |       return Yap_gmp_rem_big_big(t1, t2); | 
					
						
							|  |  |  |     case double_e: | 
					
						
							|  |  |  |       return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "mod/2"); | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       RERROR(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   default: | 
					
						
							|  |  |  |     RERROR(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Term | 
					
						
							|  |  |  | p_rdiv(Term t1, Term t2) { | 
					
						
							| 
									
										
										
										
											2010-06-01 01:07:36 +01:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |   switch (ETypeOfTerm(t1)) { | 
					
						
							|  |  |  |   case (CELL)double_e: | 
					
						
							|  |  |  |     return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "rdiv/2"); | 
					
						
							|  |  |  |   case (CELL)long_int_e: | 
					
						
							|  |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							|  |  |  |     case (CELL)long_int_e: | 
					
						
							|  |  |  |       /* two integers */ | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  | 	Int i1 = IntegerOfTerm(t1); | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  | 	Int i2 = IntegerOfTerm(t2); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-22 14:48:33 +01:00
										 |  |  | 	if (i2 == 0) | 
					
						
							|  |  |  | 	  return Yap_ArithError(EVALUATION_ERROR_ZERO_DIVISOR, t2, "X is " Int_FORMAT " rdiv 0", i1); | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  | 	return Yap_gmq_rdiv_int_int(i1, i2); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     case (CELL)big_int_e: | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       /* I know the term is much larger, so: */ | 
					
						
							|  |  |  |       return Yap_gmq_rdiv_int_big(IntegerOfTerm(t1), t2); | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       RERROR(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case (CELL)big_int_e: | 
					
						
							|  |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							|  |  |  |     case long_int_e: | 
					
						
							| 
									
										
										
										
											2011-04-22 14:48:33 +01:00
										 |  |  |       if (IntegerOfTerm(t2) == 0) | 
					
						
							|  |  |  | 	return Yap_ArithError(EVALUATION_ERROR_ZERO_DIVISOR, t2, "X is ... rdiv  0"); | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       /* I know the term is much larger, so: */ | 
					
						
							|  |  |  |       return Yap_gmq_rdiv_big_int(t1, IntegerOfTerm(t2)); | 
					
						
							|  |  |  |     case (CELL)big_int_e: | 
					
						
							|  |  |  |       return Yap_gmq_rdiv_big_big(t1, t2); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case double_e: | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  |       return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "mod/2"); | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       RERROR(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |   default: | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     RERROR(); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-06-01 01:07:36 +01:00
										 |  |  | #else
 | 
					
						
							|  |  |  |   RERROR(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |   Floating point division: / | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | static Term | 
					
						
							|  |  |  | p_fdiv(Term t1, Term t2) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   switch (ETypeOfTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   case long_int_e: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case long_int_e: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Int i2 = IntegerOfTerm(t2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* two integers */ | 
					
						
							|  |  |  | 	RFLOAT((((Float)IntegerOfTerm(t1))/(Float)i2)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     case double_e: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	/* integer, double */ | 
					
						
							|  |  |  | 	Float fl1 = (Float)IntegerOfTerm(t1); | 
					
						
							|  |  |  | 	Float fl2 = FloatOfTerm(t2); | 
					
						
							|  |  |  | 	RFLOAT(fl1/fl2); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     case (CELL)big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return Yap_gmp_fdiv_int_big(IntegerOfTerm(t1), t2); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |       RERROR(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case double_e: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case long_int_e: | 
					
						
							|  |  |  |       /* float / integer */ | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Int i2 = IntegerOfTerm(t2); | 
					
						
							|  |  |  | 	RFLOAT(FloatOfTerm(t1)/(Float)i2); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     case double_e: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Float f2 = FloatOfTerm(t2); | 
					
						
							|  |  |  | 	RFLOAT(FloatOfTerm(t1)/f2); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     case big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return Yap_gmp_fdiv_float_big(FloatOfTerm(t1), t2); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |       RERROR(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case long_int_e: | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return Yap_gmp_fdiv_big_int(t1, IntegerOfTerm(t2)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case big_int_e: | 
					
						
							|  |  |  |       /* two bignums*/ | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return Yap_gmp_fdiv_big_big(t1, t2); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case double_e: | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return Yap_gmp_fdiv_big_float(t1, FloatOfTerm(t2)); | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       RERROR(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |   default: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     RERROR(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   RERROR(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |   xor # | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | static Term | 
					
						
							|  |  |  | p_xor(Term t1, Term t2) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   switch (ETypeOfTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   case long_int_e: | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case long_int_e: | 
					
						
							|  |  |  |       /* two integers */ | 
					
						
							|  |  |  |       RINT(IntegerOfTerm(t1) ^ IntegerOfTerm(t2)); | 
					
						
							|  |  |  |     case double_e: | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  |       return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "#/2"); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return Yap_gmp_xor_int_big(IntegerOfTerm(t1), t2); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |       RERROR(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case double_e: | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  |     return Yap_ArithError(TYPE_ERROR_INTEGER, t1, "#/2"); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   case big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case long_int_e: | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return Yap_gmp_xor_int_big(IntegerOfTerm(t2), t1); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case big_int_e: | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return Yap_gmp_xor_big_big(t1, t2); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case double_e: | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  |       return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "#/2"); | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       RERROR(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2006-01-02 23:19:10 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |   default: | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     RERROR(); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   RERROR(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |   atan2: arc tangent x/y | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | static Term | 
					
						
							|  |  |  | p_atan2(Term t1, Term t2) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   switch (ETypeOfTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   case long_int_e: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case long_int_e: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |       /* two integers */ | 
					
						
							|  |  |  |       RFLOAT(atan2(IntegerOfTerm(t1),IntegerOfTerm(t2))); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case double_e: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |       RFLOAT(atan2(IntegerOfTerm(t1),FloatOfTerm(t2))); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       { | 
					
						
							|  |  |  | 	Int i1 = IntegerOfTerm(t1); | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  | 	Float f2 = Yap_gmp_to_float(t2); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	RFLOAT(atan2(i1,f2)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |       RERROR(); | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   case double_e: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case long_int_e: | 
					
						
							|  |  |  |       /* float / integer */ | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Int i2 = IntegerOfTerm(t2); | 
					
						
							|  |  |  | 	RFLOAT(atan2(FloatOfTerm(t1),i2)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     case double_e: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Float f2 = FloatOfTerm(t2); | 
					
						
							|  |  |  | 	RFLOAT(atan2(FloatOfTerm(t1),f2)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     case big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  | 	RFLOAT(atan2(FloatOfTerm(t1),Yap_gmp_to_float(t2))); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |       RERROR(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |       Float dbl1 = Yap_gmp_to_float(t1); | 
					
						
							|  |  |  |       switch (ETypeOfTerm(t2)) { | 
					
						
							|  |  |  |       case long_int_e: | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	  Int i = IntegerOfTerm(t2); | 
					
						
							|  |  |  | 	  RFLOAT(atan2(dbl1,i)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       case big_int_e: | 
					
						
							|  |  |  | 	/* two bignums */ | 
					
						
							|  |  |  | 	RFLOAT(atan2(dbl1,Yap_gmp_to_float(t2))); | 
					
						
							|  |  |  |       case double_e: | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	  Float dbl = FloatOfTerm(t2); | 
					
						
							|  |  |  | 	  RFLOAT(atan2(dbl1,dbl)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       default: | 
					
						
							|  |  |  | 	RERROR(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |   default: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     RERROR(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   RERROR(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |   power: x^y | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | static Term | 
					
						
							|  |  |  | p_power(Term t1, Term t2) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   switch (ETypeOfTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   case long_int_e: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case long_int_e: | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | 	Int i2 = IntegerOfTerm(t2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* two integers */ | 
					
						
							|  |  |  | 	RFLOAT(pow(IntegerOfTerm(t1),i2)); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case double_e: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |       { | 
					
						
							|  |  |  | 	/* integer, double */ | 
					
						
							|  |  |  | 	Float fl1 = (Float)IntegerOfTerm(t1); | 
					
						
							|  |  |  | 	Float fl2 = FloatOfTerm(t2); | 
					
						
							|  |  |  | 	RFLOAT(pow(fl1,fl2)); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | 	Int i1 = IntegerOfTerm(t1); | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  | 	Float f2 = Yap_gmp_to_float(t2); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | 	RFLOAT(pow(i1,f2)); | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       RERROR(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     break; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   case double_e: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case long_int_e: | 
					
						
							|  |  |  |       /* float / integer */ | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |       { | 
					
						
							|  |  |  | 	Int i2 = IntegerOfTerm(t2); | 
					
						
							|  |  |  | 	RFLOAT(pow(FloatOfTerm(t1),i2)); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case double_e: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |       { | 
					
						
							|  |  |  | 	Float f2 = FloatOfTerm(t2); | 
					
						
							|  |  |  | 	RFLOAT(pow(FloatOfTerm(t1),f2)); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  | 	RFLOAT(pow(FloatOfTerm(t1),Yap_gmp_to_float(t2))); | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       RERROR(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     break; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   case big_int_e: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							|  |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case long_int_e: | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | 	Int i = IntegerOfTerm(t2); | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  | 	RFLOAT(pow(Yap_gmp_to_float(t1),i)); | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case big_int_e: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |       /* two bignums */ | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       RFLOAT(pow(Yap_gmp_to_float(t1),Yap_gmp_to_float(t2))); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     case double_e: | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | 	Float dbl = FloatOfTerm(t2); | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  | 	RFLOAT(pow(Yap_gmp_to_float(t1),dbl)); | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       RERROR(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |   default: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     RERROR(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   RERROR(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  | /* next function is adapted from:
 | 
					
						
							|  |  |  |    Inline C++ integer exponentiation routines  | 
					
						
							|  |  |  |    Version 1.01 | 
					
						
							|  |  |  |    Copyright (C) 1999-2004 John C. Bowman <bowman@math.ualberta.ca> | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | static inline Int | 
					
						
							|  |  |  | ipow(Int x, Int p) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-02 10:54:09 -05:00
										 |  |  |   Int r; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-11 00:18:12 +01:00
										 |  |  |   if (p == 0) return ((CELL)1); | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  |   if (x == 0 && p > 0) return 0L; | 
					
						
							|  |  |  |   if(p < 0)  | 
					
						
							| 
									
										
										
										
											2010-05-11 00:18:12 +01:00
										 |  |  |     return (-p % 2) ? x : ((CELL)1); | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2010-05-11 00:18:12 +01:00
										 |  |  |   r = ((CELL)1); | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  |   for(;;) { | 
					
						
							|  |  |  |     if(p & 1) { | 
					
						
							|  |  |  |       if (mul_overflow((r*x), r, x)) { | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       r *= x; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if((p >>= 1) == 0)	return r; | 
					
						
							|  |  |  |     if (mul_overflow((x*x), x, x)) { | 
					
						
							|  |  |  |       return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     x *= x; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |   power: x^y | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | static Term | 
					
						
							|  |  |  | p_exp(Term t1, Term t2) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   switch (ETypeOfTerm(t1)) { | 
					
						
							|  |  |  |   case long_int_e: | 
					
						
							|  |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							|  |  |  |     case long_int_e: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Int i1 = IntegerOfTerm(t1); | 
					
						
							|  |  |  | 	Int i2 = IntegerOfTerm(t2); | 
					
						
							|  |  |  | 	Int pow = ipow(i1,i2); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-07 23:42:16 -04:00
										 |  |  | 	if (i2 < 0) { | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  | 	  return Yap_ArithError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, t2, | 
					
						
							| 
									
										
										
										
											2009-05-07 23:42:16 -04:00
										 |  |  | 		    "%d ^ %d", i1, i2); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							|  |  |  | 	/* two integers */ | 
					
						
							| 
									
										
										
										
											2009-05-07 23:42:16 -04:00
										 |  |  | 	if ((i1 && !pow)) { | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  | 	  /* overflow */ | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  | 	  return Yap_gmp_exp_int_int(i1, i2); | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	RINT(pow); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     case double_e: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	/* integer, double */ | 
					
						
							|  |  |  | 	Float fl1 = (Float)IntegerOfTerm(t1); | 
					
						
							|  |  |  | 	Float fl2 = FloatOfTerm(t2); | 
					
						
							|  |  |  | 	RFLOAT(pow(fl1,fl2)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     case big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  | 	Int i = IntegerOfTerm(t1); | 
					
						
							|  |  |  | 	return Yap_gmp_exp_int_big(i,t2); | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  |       } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  |       RERROR(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case double_e: | 
					
						
							|  |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							|  |  |  |     case long_int_e: | 
					
						
							|  |  |  |       /* float / integer */ | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Int i2 = IntegerOfTerm(t2); | 
					
						
							|  |  |  | 	RFLOAT(pow(FloatOfTerm(t1),i2)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     case double_e: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Float f2 = FloatOfTerm(t2); | 
					
						
							|  |  |  | 	RFLOAT(pow(FloatOfTerm(t1),f2)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     case big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  | 	RFLOAT(pow(FloatOfTerm(t1),Yap_gmp_to_float(t2))); | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  |       } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  |       RERROR(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case big_int_e: | 
					
						
							|  |  |  | #ifdef USE_GMP
 | 
					
						
							|  |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							|  |  |  |     case long_int_e: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Int i = IntegerOfTerm(t2); | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  | 	return Yap_gmp_exp_big_int(t1,i); | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  |       } | 
					
						
							|  |  |  |     case big_int_e: | 
					
						
							|  |  |  |       /* two bignums, makes no sense */ | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return Yap_gmp_exp_big_big(t1,t2); | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  |     case double_e: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Float dbl = FloatOfTerm(t2); | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  | 	RFLOAT(pow(Yap_gmp_to_float(t1),dbl)); | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  |       RERROR(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |   default: | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  |     RERROR(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   RERROR(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | static Int | 
					
						
							|  |  |  | gcd(Int m11,Int m21) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   /* Blankinship algorithm, provided by Miguel Filgueiras */ | 
					
						
							|  |  |  |   Int m12=1, m22=0, k; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   while (m11>0 && m21>0) | 
					
						
							|  |  |  |     if (m11<m21) { | 
					
						
							|  |  |  |       k = m21/m11;  m21 -= k*m11;  m22 -= k*m12; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       k=m11/m21;  m11 -= k*m21;  m12 -= k*m22; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   if (m11<0 || m21<0) {		/* overflow? */ | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     /*    Oflow = 1; */ | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  |     Yap_ArithError(EVALUATION_ERROR_INT_OVERFLOW, MkIntegerTerm(m11), | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | 	      "gcd/2 with %d and %d", m11, m21); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return(1); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (m11)  return(m11); | 
					
						
							|  |  |  |   return(m21); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef GCD_MULT
 | 
					
						
							|  |  |  | Int gcdmult(Int m11,Int m21,Int *pm11)	/* *pm11 gets multiplier of m11 */ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Int m12=1, m22=0, k; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   while (m11 && m21) | 
					
						
							|  |  |  |     if (m11<m21) { | 
					
						
							|  |  |  |       k = m21/m11;  m21 -= k*m11;  m22 -= k*m12; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       k=m11/m21;  m11 -= k*m21;  m12 -= k*m22; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   if (m11<0 || m21<0) {		/* overflow? */ | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     /*    Oflow = 1; */ | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  |     Yap_ArithError(EVALUATION_ERROR_INT_OVERFLOW, MkIntegerTerm(m11), | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | 	      "gcdmult/2 with %d and %d", m11, m21); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return(1); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (m11) { | 
					
						
							|  |  |  |     *pm11 = m12;  return(m11); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   *pm11 = m22; | 
					
						
							|  |  |  |   return(m21); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |   module gcd | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | static Term | 
					
						
							|  |  |  | p_gcd(Term t1, Term t2) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   switch (ETypeOfTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   case long_int_e: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case long_int_e: | 
					
						
							|  |  |  |       /* two integers */ | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Int i1 = IntegerOfTerm(t1), i2 = IntegerOfTerm(t2); | 
					
						
							|  |  |  | 	i1 = (i1 >= 0 ? i1 : -i1); | 
					
						
							|  |  |  | 	i2 = (i2 >= 0 ? i2 : -i2); | 
					
						
							| 
									
										
										
										
											2010-08-04 22:09:08 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	RINT(gcd(i1,i2)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     case double_e: | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  |       return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "gcd/2"); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return Yap_gmp_gcd_int_big(IntegerOfTerm(t1), t2); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |       RERROR(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case double_e: | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  |     return Yap_ArithError(TYPE_ERROR_INTEGER, t1, "gcd/2"); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   case big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case long_int_e: | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return Yap_gmp_gcd_int_big(IntegerOfTerm(t2), t1); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case big_int_e: | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return Yap_gmp_gcd_big_big(t1, t2); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case double_e: | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  |       return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "gcd/2"); | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       RERROR(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |   default: | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     RERROR(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   RERROR(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |   minimum: min(x,y) | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | static Term | 
					
						
							|  |  |  | p_min(Term t1, Term t2) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   switch (ETypeOfTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   case long_int_e: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case long_int_e: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Int i1 = IntegerOfTerm(t1); | 
					
						
							|  |  |  | 	Int i2 = IntegerOfTerm(t2); | 
					
						
							| 
									
										
										
										
											2009-06-05 10:38:07 -05:00
										 |  |  | 	return((i1 < i2 ? t1 : t2)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     case double_e: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	/* integer, double */ | 
					
						
							|  |  |  | 	Int i = IntegerOfTerm(t1); | 
					
						
							|  |  |  | 	Float fl = FloatOfTerm(t2); | 
					
						
							|  |  |  | 	if (i <= fl) { | 
					
						
							| 
									
										
										
										
											2009-06-05 10:38:07 -05:00
										 |  |  | 	  return t1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-06-05 10:38:07 -05:00
										 |  |  | 	return t2; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     case big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       if (Yap_gmp_cmp_int_big(IntegerOfTerm(t1), t2) < 0) { | 
					
						
							| 
									
										
										
										
											2009-06-05 10:38:07 -05:00
										 |  |  | 	return t1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return t2; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |       RERROR(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case double_e: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case long_int_e: | 
					
						
							|  |  |  |       /* float / integer */ | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Int i = IntegerOfTerm(t2); | 
					
						
							|  |  |  | 	Float fl = FloatOfTerm(t1); | 
					
						
							|  |  |  | 	if (i <= fl) { | 
					
						
							| 
									
										
										
										
											2009-06-05 10:38:07 -05:00
										 |  |  | 	  return t2; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-06-05 10:38:07 -05:00
										 |  |  | 	return t1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     case double_e: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Float fl1 = FloatOfTerm(t1); | 
					
						
							|  |  |  | 	Float fl2 = FloatOfTerm(t2); | 
					
						
							|  |  |  | 	if (fl1 <= fl2) { | 
					
						
							| 
									
										
										
										
											2009-06-05 10:38:07 -05:00
										 |  |  | 	  return t1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-06-05 10:38:07 -05:00
										 |  |  | 	return t2; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     case big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       if (Yap_gmp_cmp_float_big(FloatOfTerm(t1), t2) < 0) { | 
					
						
							|  |  |  | 	return t1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return t2; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |       RERROR(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case long_int_e: | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       if (Yap_gmp_cmp_big_int(t1, IntegerOfTerm(t2)) < 0) { | 
					
						
							|  |  |  | 	return t1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return t2; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case big_int_e: | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       if (Yap_gmp_cmp_big_big(t1, t2) < 0) { | 
					
						
							|  |  |  | 	return t1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return t2; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case double_e: | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       if (Yap_gmp_cmp_big_float(t1, FloatOfTerm(t2)) < 0) { | 
					
						
							|  |  |  | 	return t1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return t2; | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       RERROR(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |   default: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     RERROR(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   RERROR(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |   maximum: max(x,y) | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | static Term | 
					
						
							|  |  |  | p_max(Term t1, Term t2) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   switch (ETypeOfTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   case long_int_e: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case long_int_e: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Int i1 = IntegerOfTerm(t1); | 
					
						
							|  |  |  | 	Int i2 = IntegerOfTerm(t2); | 
					
						
							| 
									
										
										
										
											2009-06-05 10:38:07 -05:00
										 |  |  | 	return((i1 > i2 ? t1 : t2)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     case double_e: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	/* integer, double */ | 
					
						
							|  |  |  | 	Int i = IntegerOfTerm(t1); | 
					
						
							|  |  |  | 	Float fl = FloatOfTerm(t2); | 
					
						
							|  |  |  | 	if (i >= fl) { | 
					
						
							| 
									
										
										
										
											2009-06-05 10:38:07 -05:00
										 |  |  | 	  return t1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-06-05 10:38:07 -05:00
										 |  |  | 	return t2; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     case big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       if (Yap_gmp_cmp_int_big(IntegerOfTerm(t1), t2) > 0) { | 
					
						
							| 
									
										
										
										
											2009-06-05 10:38:07 -05:00
										 |  |  | 	return t1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return t2; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |       RERROR(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case double_e: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case long_int_e: | 
					
						
							|  |  |  |       /* float / integer */ | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Int i = IntegerOfTerm(t2); | 
					
						
							|  |  |  | 	Float fl = FloatOfTerm(t1); | 
					
						
							|  |  |  | 	if (i >= fl) { | 
					
						
							| 
									
										
										
										
											2009-06-05 10:38:07 -05:00
										 |  |  | 	  return t2; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-06-05 10:38:07 -05:00
										 |  |  | 	return t1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     case double_e: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Float fl1 = FloatOfTerm(t1); | 
					
						
							|  |  |  | 	Float fl2 = FloatOfTerm(t2); | 
					
						
							|  |  |  | 	if (fl1 >= fl2) { | 
					
						
							| 
									
										
										
										
											2009-06-05 10:38:07 -05:00
										 |  |  | 	  return t1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-06-05 10:38:07 -05:00
										 |  |  | 	return t2; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     case big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       if (Yap_gmp_cmp_float_big(FloatOfTerm(t1), t2) > 0) { | 
					
						
							|  |  |  | 	return t1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return t2; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |       RERROR(); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case big_int_e: | 
					
						
							| 
									
										
										
										
											2009-06-15 10:11:05 -05:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case long_int_e: | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       if (Yap_gmp_cmp_big_int(t1, IntegerOfTerm(t2)) > 0) { | 
					
						
							|  |  |  | 	return t1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return t2; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case big_int_e: | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       if (Yap_gmp_cmp_big_big(t1, t2) > 0) { | 
					
						
							|  |  |  | 	return t1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return t2; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     case double_e: | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       if (Yap_gmp_cmp_big_float(t1, FloatOfTerm(t2)) > 0) { | 
					
						
							|  |  |  | 	return t1; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |       return t2; | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       RERROR(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-03-06 22:43:21 +00:00
										 |  |  |   default: | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     RERROR(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   RERROR(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | static Term | 
					
						
							|  |  |  | eval2(Int fi, Term t1, Term t2) { | 
					
						
							|  |  |  |   arith2_op f = fi; | 
					
						
							|  |  |  |   switch (f) { | 
					
						
							|  |  |  |   case op_plus: | 
					
						
							|  |  |  |     return p_plus(t1, t2); | 
					
						
							|  |  |  |   case op_minus: | 
					
						
							|  |  |  |     return p_minus(t1, t2); | 
					
						
							|  |  |  |   case op_times: | 
					
						
							|  |  |  |     return p_times(t1, t2); | 
					
						
							|  |  |  |   case op_div: | 
					
						
							|  |  |  |     return p_div(t1, t2); | 
					
						
							| 
									
										
										
										
											2010-08-30 21:50:33 -05:00
										 |  |  |   case op_idiv: | 
					
						
							|  |  |  |     return p_div2(t1, t2); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   case op_and: | 
					
						
							|  |  |  |     return p_and(t1, t2); | 
					
						
							|  |  |  |   case op_or: | 
					
						
							|  |  |  |     return p_or(t1, t2); | 
					
						
							|  |  |  |   case op_sll: | 
					
						
							|  |  |  |     return p_sll(t1, t2); | 
					
						
							|  |  |  |   case op_slr: | 
					
						
							|  |  |  |     return p_slr(t1, t2); | 
					
						
							|  |  |  |   case op_mod: | 
					
						
							|  |  |  |     return p_mod(t1, t2); | 
					
						
							|  |  |  |   case op_rem: | 
					
						
							|  |  |  |     return p_rem(t1, t2); | 
					
						
							|  |  |  |   case op_fdiv: | 
					
						
							|  |  |  |     return p_fdiv(t1, t2); | 
					
						
							|  |  |  |   case op_xor: | 
					
						
							|  |  |  |     return p_xor(t1, t2); | 
					
						
							|  |  |  |   case op_atan2: | 
					
						
							|  |  |  |     return p_atan2(t1, t2); | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  |   case op_power: | 
					
						
							|  |  |  |     return p_exp(t1, t2); | 
					
						
							| 
									
										
										
										
											2009-05-09 23:39:57 -04:00
										 |  |  |   case op_power2: | 
					
						
							|  |  |  |     return p_power(t1, t2); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   case op_gcd: | 
					
						
							|  |  |  |     return p_gcd(t1, t2); | 
					
						
							|  |  |  |   case op_min: | 
					
						
							|  |  |  |     return p_min(t1, t2); | 
					
						
							|  |  |  |   case op_max: | 
					
						
							|  |  |  |     return p_max(t1, t2); | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |   case op_rdiv: | 
					
						
							|  |  |  |     return p_rdiv(t1, t2); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   RERROR(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | Term Yap_eval_binary(Int f, Term t1, Term t2) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-03 15:43:07 -02:00
										 |  |  |   return eval2(f,t1,t2); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static InitBinEntry InitBinTab[] = { | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   {"+", op_plus}, | 
					
						
							|  |  |  |   {"-", op_minus}, | 
					
						
							|  |  |  |   {"*", op_times}, | 
					
						
							|  |  |  |   {"/", op_fdiv}, | 
					
						
							|  |  |  |   {"mod", op_mod}, | 
					
						
							|  |  |  |   {"rem", op_rem}, | 
					
						
							|  |  |  |   {"//", op_div}, | 
					
						
							| 
									
										
										
										
											2010-08-30 21:50:33 -05:00
										 |  |  |   {"div", op_idiv}, | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   {"<<", op_sll}, | 
					
						
							|  |  |  |   {">>", op_slr}, | 
					
						
							|  |  |  |   {"/\\", op_and}, | 
					
						
							|  |  |  |   {"\\/", op_or}, | 
					
						
							|  |  |  |   {"#", op_xor}, | 
					
						
							| 
									
										
										
										
											2009-07-23 14:31:04 -05:00
										 |  |  |   {"><", op_xor}, | 
					
						
							| 
									
										
										
										
											2010-09-21 22:26:24 +01:00
										 |  |  |   {"xor", op_xor}, | 
					
						
							| 
									
										
										
										
											2010-09-27 22:01:38 +01:00
										 |  |  |   {"atan", op_atan2}, | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   {"atan2", op_atan2}, | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   /* C-Prolog exponentiation */ | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   {"^", op_power}, | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   /* ISO-Prolog exponentiation */ | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  |   {"**", op_power2}, | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   /* Quintus exponentiation */ | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  |   {"exp", op_power2}, | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   {"gcd", op_gcd}, | 
					
						
							|  |  |  |   {"min", op_min}, | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |   {"max", op_max}, | 
					
						
							|  |  |  |   {"rdiv", op_rdiv} | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_binary_is( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | {				/* X is Y	 */ | 
					
						
							|  |  |  |   Term t = Deref(ARG2); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   Term t1, t2; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t)) { | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  |     Yap_ArithError(INSTANTIATION_ERROR,t, "X is Y"); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return(FALSE); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   t1 = Yap_Eval(Deref(ARG3)); | 
					
						
							| 
									
										
										
										
											2010-02-22 22:48:13 +00:00
										 |  |  |   if (!Yap_FoundArithError(t1, ARG3)) { | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2010-02-22 22:48:13 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   t2 = Yap_Eval(Deref(ARG4)); | 
					
						
							| 
									
										
										
										
											2010-02-22 22:48:13 +00:00
										 |  |  |   if (!Yap_FoundArithError(t2, ARG4)) { | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2010-02-22 22:48:13 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   if (IsIntTerm(t)) { | 
					
						
							| 
									
										
										
										
											2010-02-22 22:48:13 +00:00
										 |  |  |     Term tout = Yap_FoundArithError(eval2(IntOfTerm(t), t1, t2), 0L); | 
					
						
							| 
									
										
										
										
											2009-05-09 23:30:08 -04:00
										 |  |  |     if (!tout) | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     return Yap_unify_constant(ARG1,tout); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   if (IsAtomTerm(t)) { | 
					
						
							|  |  |  |     Atom name = AtomOfTerm(t); | 
					
						
							|  |  |  |     ExpEntry *p; | 
					
						
							| 
									
										
										
										
											2009-05-09 23:30:08 -04:00
										 |  |  |     Term out; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     if (EndOfPAEntr(p = RepExpProp(Yap_GetExpProp(name, 2)))) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       Term ti[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* error */ | 
					
						
							|  |  |  |       ti[0] = t; | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |       ti[1] = MkIntTerm(1); | 
					
						
							| 
									
										
										
										
											2008-12-23 01:53:52 +00:00
										 |  |  |       t = Yap_MkApplTerm(FunctorSlash, 2, ti); | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |       Yap_Error(TYPE_ERROR_EVALUABLE, t, | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | 		"functor %s/%d for arithmetic expression", | 
					
						
							|  |  |  | 		RepAtom(name)->StrOfAE,2); | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  |       P = FAILCODE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       return(FALSE); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  |     if (!(out=Yap_FoundArithError(eval2(p->FOfEE, t1, t2), 0L))) | 
					
						
							| 
									
										
										
										
											2009-05-09 23:30:08 -04:00
										 |  |  |       return FALSE; | 
					
						
							|  |  |  |     return Yap_unify_constant(ARG1,out); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-05-09 23:30:08 -04:00
										 |  |  |   return FALSE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | do_arith23(arith2_op op USES_REGS) | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  | {				/* X is Y	 */ | 
					
						
							|  |  |  |   Term t = Deref(ARG1); | 
					
						
							|  |  |  |   Int out; | 
					
						
							|  |  |  |   Term t1, t2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t)) { | 
					
						
							|  |  |  |     Yap_ArithError(INSTANTIATION_ERROR,t, "X is Y"); | 
					
						
							|  |  |  |     return(FALSE); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   t1 = Yap_Eval(t); | 
					
						
							|  |  |  |   if (t1 == 0L) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   t2 = Yap_Eval(Deref(ARG2)); | 
					
						
							|  |  |  |   if (t2 == 0L) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   if (!(out=Yap_FoundArithError(eval2(op, t1, t2), 0L))) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   return Yap_unify_constant(ARG3,out); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | export_p_plus( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  | {				/* X is Y	 */ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   return do_arith23(op_plus PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | export_p_minus( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  | {				/* X is Y	 */ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   return do_arith23(op_minus PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | export_p_times( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  | {				/* X is Y	 */ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   return do_arith23(op_times PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | export_p_div( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  | {				/* X is Y	 */ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   return do_arith23(op_div PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | export_p_and( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  | {				/* X is Y	 */ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   return do_arith23(op_and PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | export_p_or( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  | {				/* X is Y	 */ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   return do_arith23(op_or PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | export_p_slr( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  | {				/* X is Y	 */ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   return do_arith23(op_slr PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | export_p_sll( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  | {				/* X is Y	 */ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   return do_arith23(op_sll PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-25 00:12:36 +00:00
										 |  |  | static Int  | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_binary_op_as_integer( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2009-02-25 00:12:36 +00:00
										 |  |  | {				/* X is Y	 */ | 
					
						
							|  |  |  |   Term t = Deref(ARG1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t)) { | 
					
						
							|  |  |  |     Yap_Error(INSTANTIATION_ERROR,t, "X is Y"); | 
					
						
							|  |  |  |     return(FALSE); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (IsIntTerm(t)) { | 
					
						
							|  |  |  |     return Yap_unify_constant(ARG2,t); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (IsAtomTerm(t)) { | 
					
						
							|  |  |  |     Atom name = AtomOfTerm(t); | 
					
						
							|  |  |  |     ExpEntry *p; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (EndOfPAEntr(p = RepExpProp(Yap_GetExpProp(name, 2)))) { | 
					
						
							| 
									
										
										
										
											2010-03-06 00:16:49 +00:00
										 |  |  |       return Yap_unify(ARG1,ARG2); | 
					
						
							| 
									
										
										
										
											2009-02-25 00:12:36 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     return Yap_unify_constant(ARG2,MkIntTerm(p->FOfEE)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return(FALSE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | void | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  | Yap_InitBinaryExps(void) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   unsigned int    i; | 
					
						
							|  |  |  |   ExpEntry       *p; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (i = 0; i < sizeof(InitBinTab)/sizeof(InitBinEntry); ++i) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     AtomEntry *ae = RepAtom(Yap_LookupAtom(InitBinTab[i].OpName)); | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  |     if (ae == NULL) { | 
					
						
							|  |  |  |       Yap_Error(OUT_OF_HEAP_ERROR,TermNil,"at InitBinaryExps"); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     WRITE_LOCK(ae->ARWLock); | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     if (Yap_GetExpPropHavingLock(ae, 2)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       WRITE_UNLOCK(ae->ARWLock); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     p = (ExpEntry *) Yap_AllocAtomSpace(sizeof(ExpEntry)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     p->KindOfPE = ExpProperty; | 
					
						
							|  |  |  |     p->ArityOfEE = 2; | 
					
						
							|  |  |  |     p->ENoOfEE = 2; | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |     p->FOfEE = InitBinTab[i].f; | 
					
						
							| 
									
										
										
										
											2011-08-17 11:16:21 -07:00
										 |  |  |     AddPropToAtom(ae, (PropEntry *)p); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     WRITE_UNLOCK(ae->ARWLock); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |   Yap_InitCPred("is", 4, p_binary_is, TestPredFlag | SafePredFlag); | 
					
						
							| 
									
										
										
										
											2009-02-25 00:12:36 +00:00
										 |  |  |   Yap_InitCPred("$binary_op_as_integer", 2, p_binary_op_as_integer, TestPredFlag|SafePredFlag); | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  |   Yap_InitAsmPred("$plus", 3, _plus, export_p_plus, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitAsmPred("$minus", 3, _minus, export_p_minus, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitAsmPred("$times", 3, _times, export_p_times, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitAsmPred("$div", 3, _div, export_p_div, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitAsmPred("$and", 3, _and, export_p_and, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitAsmPred("$or", 3, _or, export_p_or, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitAsmPred("$sll", 3, _sll, export_p_sll, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitAsmPred("$slr", 3, _slr, export_p_slr, SafePredFlag); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* This routine is called from Restore to make sure we have the same arithmetic operators */ | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  | Yap_ReInitBinaryExps(void) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   return(TRUE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |