| 
									
										
										
										
											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
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-21 11:14:18 +01:00
										 |  |  | /**
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    @file arith2.c | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    @addtogroup arithmetic_operators | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | These are the binary numeric operators currently supported by YAP. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> _X_+ _Y_ [ISO]</b><p> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Sum. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> _X_- _Y_ [ISO]</b><p> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Difference. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> _X_\* _Y_ [ISO]</b><p> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Product. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> _X_/ _Y_ [ISO]</b><p> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Quotient. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> _X_// _Y_ [ISO]</b><p>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Integer quotient. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> _X_ mod  _Y_ [ISO]</b><p> @anchor mod_2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Integer module operator, always positive. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> _X_ rem  _Y_ [ISO]</b><p> @anchor rem_2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Integer remainder, similar to `mod` but always has the same sign as `X`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b>  _X_ div  _Y_ [ISO]</b><p> @anchor div_2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Integer division, as if defined by `( _X_ -  _X_ mod  _Y_)//  _Y_`.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> max( _X_, _Y_) [ISO]</b><p> @anchor max_2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     The greater value of  _X_ and  _Y_. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> min( _X_, _Y_) [ISO]</b><p> @anchor min_2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     The lesser value of  _X_ and  _Y_. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> _X_ ^  _Y_ [ISO]</b><p> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |      _X_ raised to the power of  _Y_, (from the C-Prolog syntax). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> exp( _X_, _Y_)</b><p> @anchor exp_2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |      _X_ raised to the power of  _Y_, (from the Quintus Prolog syntax). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> _X_ \*\*  _Y_ [ISO]</b><p> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |      _X_ raised to the power of  _Y_  (from ISO). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> _X_ /\\  _Y_ [ISO]</b><p> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Integer bitwise conjunction. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> _X_ \\/  _Y_ [ISO]</b><p> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Integer bitwise disjunction. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> _X_ #  _Y_</b><p> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Integer bitwise exclusive disjunction. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> _X_ \>\<  _Y_</b><p> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Integer bitwise exclusive disjunction. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> xor( _X_ ,  _Y_) [ISO]</b><p> @anchor xor_2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Integer bitwise exclusive disjunction. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> _X_ \<\<  _Y_</b><p> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Integer bitwise left logical shift of  _X_ by  _Y_ places. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> _X_ \>\>  _Y_ [ISO]</b><p> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Integer bitwise right logical shift of  _X_ by  _Y_ places. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> gcd( _X_, _Y_)</b><p> @anchor gcd_2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     The greatest common divisor of the two integers  _X_ and  _Y_. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> atan( _X_, _Y_)</b><p> @anchor atan_2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Four-quadrant arc tangent. Also available as `atan2/2`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b> atan2( _X_, _Y_) [ISO]</b><p> @anchor atan2_2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Four-quadrant arc tangent. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - <b>  _X_ rdiv  _Y_ [ISO]</b><p> @anchor rdiv_2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Rational division. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #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 | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  | p_mod(Term t1, Term t2 USES_REGS) { | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   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) { | 
					
						
							| 
									
										
										
										
											2013-02-12 16:45:03 -06:00
										 |  |  | 	  return MkIntTerm(0); | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  | p_div2(Term t1, Term t2 USES_REGS) { | 
					
						
							| 
									
										
										
										
											2010-08-30 21:50:33 -05:00
										 |  |  |   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: | 
					
						
							| 
									
										
										
										
											2014-10-22 16:50:12 +01:00
										 |  |  |       return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "div/2"); | 
					
						
							| 
									
										
										
										
											2010-08-30 21:50:33 -05:00
										 |  |  |     default: | 
					
						
							|  |  |  |       RERROR(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   default: | 
					
						
							|  |  |  |     RERROR(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  | static Term | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  | p_rem(Term t1, Term t2 USES_REGS) { | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   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) { | 
					
						
							| 
									
										
										
										
											2013-02-12 16:45:03 -06:00
										 |  |  | 	  return MkIntTerm(0); | 
					
						
							| 
									
										
										
										
											2009-02-09 21:56:40 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  | 	RINT(i1%i2); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     case (CELL)double_e: | 
					
						
							| 
									
										
										
										
											2014-10-22 16:50:12 +01:00
										 |  |  |       return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "rem/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: | 
					
						
							| 
									
										
										
										
											2014-10-22 16:50:12 +01:00
										 |  |  |     return Yap_ArithError(TYPE_ERROR_INTEGER, t1, "rem/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: | 
					
						
							| 
									
										
										
										
											2014-10-22 16:50:12 +01:00
										 |  |  |       return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "rem/2"); | 
					
						
							| 
									
										
										
										
											2010-05-27 12:24:15 +01:00
										 |  |  |     default: | 
					
						
							|  |  |  |       RERROR(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   default: | 
					
						
							|  |  |  |     RERROR(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Term | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  | p_rdiv(Term t1, Term t2 USES_REGS) { | 
					
						
							| 
									
										
										
										
											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: | 
					
						
							| 
									
										
										
										
											2014-10-22 16:50:12 +01:00
										 |  |  |       return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "rdiv/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 | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  | p_fdiv(Term t1, Term t2 USES_REGS) | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  | p_xor(Term t1, Term t2 USES_REGS) | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  | p_atan2(Term t1, Term t2 USES_REGS) | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  | p_power(Term t1, Term t2 USES_REGS) | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  | p_exp(Term t1, Term t2 USES_REGS) | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  | { | 
					
						
							|  |  |  |   switch (ETypeOfTerm(t1)) { | 
					
						
							|  |  |  |   case long_int_e: | 
					
						
							|  |  |  |     switch (ETypeOfTerm(t2)) { | 
					
						
							|  |  |  |     case long_int_e: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Int i1 = IntegerOfTerm(t1); | 
					
						
							|  |  |  | 	Int i2 = IntegerOfTerm(t2); | 
					
						
							| 
									
										
										
										
											2014-10-20 00:33:36 +01:00
										 |  |  | 	Int pow; | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-10-20 00:33:36 +01:00
										 |  |  |     pow = ipow(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 | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  | gcd(Int m11,Int m21 USES_REGS) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   /* 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 | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  | p_gcd(Term t1, Term t2 USES_REGS) | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  | 	RINT(gcd(i1,i2 PASS_REGS)); | 
					
						
							| 
									
										
										
										
											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"); | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  | eval2(Int fi, Term t1, Term t2 USES_REGS) { | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   arith2_op f = fi; | 
					
						
							|  |  |  |   switch (f) { | 
					
						
							|  |  |  |   case op_plus: | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |     return p_plus(t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   case op_minus: | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |     return p_minus(t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   case op_times: | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |     return p_times(t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   case op_div: | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |     return p_div(t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-08-30 21:50:33 -05:00
										 |  |  |   case op_idiv: | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |     return p_div2(t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   case op_and: | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |     return p_and(t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   case op_or: | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |     return p_or(t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   case op_sll: | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |     return p_sll(t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   case op_slr: | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |     return p_slr(t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   case op_mod: | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |     return p_mod(t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   case op_rem: | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |     return p_rem(t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   case op_fdiv: | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |     return p_fdiv(t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   case op_xor: | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |     return p_xor(t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   case op_atan2: | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |     return p_atan2(t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-04-24 19:03:00 -05:00
										 |  |  |   case op_power: | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |     return p_exp(t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2009-05-09 23:39:57 -04:00
										 |  |  |   case op_power2: | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |     return p_power(t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   case op_gcd: | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |     return p_gcd(t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   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: | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |     return p_rdiv(t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-03-26 15:01:52 -05:00
										 |  |  |   CACHE_REGS | 
					
						
							|  |  |  |   return eval2(f,t1,t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											2014-10-16 10:49:11 +01:00
										 |  |  |   yap_error_number err; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(t)) { | 
					
						
							| 
									
										
										
										
											2014-10-16 10:49:11 +01:00
										 |  |  |     Yap_ArithError(INSTANTIATION_ERROR,t, "VAR(X , Y)"); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return(FALSE); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-10-15 11:06:07 +01:00
										 |  |  |   Yap_ClearExs(); | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   t1 = Yap_Eval(Deref(ARG3)); | 
					
						
							| 
									
										
										
										
											2014-10-16 10:49:11 +01:00
										 |  |  |   if ((err = Yap_FoundArithError())) { | 
					
						
							|  |  |  |     Atom name; | 
					
						
							|  |  |  |     if (IsIntTerm(t)) { | 
					
						
							|  |  |  |       Int i = IntOfTerm(t); | 
					
						
							|  |  |  |       name = Yap_NameOfBinaryOp(i); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       name = AtomOfTerm(Deref(ARG2)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     Yap_EvalError(err,ARG3,"X is ~s/2: error in first argument ", RepAtom(name)->StrOfAE); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2010-02-22 22:48:13 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-04 23:33:32 +00:00
										 |  |  |   t2 = Yap_Eval(Deref(ARG4)); | 
					
						
							| 
									
										
										
										
											2014-10-16 10:49:11 +01:00
										 |  |  |   if ((err=Yap_FoundArithError())) { | 
					
						
							|  |  |  |     Atom name; | 
					
						
							|  |  |  |     if (IsIntTerm(t)) { | 
					
						
							|  |  |  |       Int i = IntOfTerm(t); | 
					
						
							|  |  |  |       name = Yap_NameOfBinaryOp(i); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       name = AtomOfTerm(Deref(ARG2)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     Yap_EvalError(err,ARG3,"X is ~s/2: error in first argument ", RepAtom(name)->StrOfAE); | 
					
						
							| 
									
										
										
										
											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)) { | 
					
						
							| 
									
										
										
										
											2014-10-16 10:49:11 +01:00
										 |  |  |     Int i = IntOfTerm(t); | 
					
						
							|  |  |  |     Term tout = eval2(i, t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2014-10-16 23:55:34 +01:00
										 |  |  |     if ((err = Yap_FoundArithError()) != YAP_NO_ERROR) { | 
					
						
							| 
									
										
										
										
											2014-10-16 10:49:11 +01:00
										 |  |  |       Term ts[2], terr; | 
					
						
							|  |  |  |       Atom name = Yap_NameOfBinaryOp( i ); | 
					
						
							|  |  |  |       Functor f = Yap_MkFunctor( name, 2 ); | 
					
						
							|  |  |  |       ts[0] = t1; | 
					
						
							|  |  |  |       ts[1] = t2; | 
					
						
							|  |  |  |       terr = Yap_MkApplTerm( f, 2, ts ); | 
					
						
							| 
									
										
										
										
											2014-10-16 23:55:34 +01:00
										 |  |  |       Yap_EvalError(err, terr ,"error in %s/2 ", RepAtom(name)->StrOfAE); | 
					
						
							| 
									
										
										
										
											2014-10-16 10:49:11 +01:00
										 |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2014-10-15 11:06:07 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-05-09 23:30:08 -04:00
										 |  |  |     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)))) { | 
					
						
							| 
									
										
										
										
											2015-08-07 16:57:53 -05:00
										 |  |  |       Yap_EvalError(TYPE_ERROR_EVALUABLE, takeIndicator(t), | 
					
						
							| 
									
										
										
										
											2014-10-16 23:55:34 +01:00
										 |  |  | 		"functor %s/2 for arithmetic expression", | 
					
						
							|  |  |  | 		RepAtom(name)->StrOfAE); | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  |       P = FAILCODE; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       return(FALSE); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-10-15 11:06:07 +01:00
										 |  |  |     out= eval2(p->FOfEE, t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2014-10-16 23:55:34 +01:00
										 |  |  |     if ((err = Yap_FoundArithError()) != YAP_NO_ERROR) { | 
					
						
							| 
									
										
										
										
											2014-10-16 10:49:11 +01:00
										 |  |  |       Term ts[2], terr; | 
					
						
							|  |  |  |       Functor f = Yap_MkFunctor( name, 2 ); | 
					
						
							|  |  |  |       ts[0] = t1; | 
					
						
							|  |  |  |       ts[1] = t2; | 
					
						
							|  |  |  |       terr = Yap_MkApplTerm( f, 2, ts ); | 
					
						
							|  |  |  |       Yap_EvalError(err, terr ,"error in ~s/2 ", RepAtom(name)->StrOfAE); | 
					
						
							| 
									
										
										
										
											2009-05-09 23:30:08 -04:00
										 |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2014-10-15 11:06:07 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-05-09 23:30:08 -04:00
										 |  |  |     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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-15 11:06:07 +01: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; | 
					
						
							| 
									
										
										
										
											2014-10-16 10:49:11 +01:00
										 |  |  |   yap_error_number err; | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-15 11:06:07 +01:00
										 |  |  |   Yap_ClearExs(); | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  |   if (IsVarTerm(t)) { | 
					
						
							| 
									
										
										
										
											2014-10-16 10:49:11 +01:00
										 |  |  |     Yap_EvalError(INSTANTIATION_ERROR,t, "X is Y"); | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  |     return(FALSE); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   t1 = Yap_Eval(t); | 
					
						
							|  |  |  |   if (t1 == 0L) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   t2 = Yap_Eval(Deref(ARG2)); | 
					
						
							|  |  |  |   if (t2 == 0L) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2014-10-15 11:06:07 +01:00
										 |  |  |   out= eval2(op, t1, t2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2014-10-16 10:49:11 +01:00
										 |  |  |   if ((err=Yap_FoundArithError())) { | 
					
						
							|  |  |  |       Term ts[2], t; | 
					
						
							|  |  |  |       Functor f = Yap_MkFunctor( Yap_NameOfBinaryOp(op), 2 ); | 
					
						
							|  |  |  |       ts[0] = t1; | 
					
						
							|  |  |  |       ts[1] = t2; | 
					
						
							|  |  |  |       t = Yap_MkApplTerm( f, 2, ts ); | 
					
						
							|  |  |  |       Yap_EvalError(err, t ,"error in ~s(Y,Z) ",Yap_NameOfBinaryOp(op)); | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2014-10-15 11:06:07 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-07-22 17:01:30 -05:00
										 |  |  |   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)) { | 
					
						
							| 
									
										
										
										
											2014-10-16 10:49:11 +01:00
										 |  |  |     Yap_EvalError(INSTANTIATION_ERROR,t, "X is Y"); | 
					
						
							| 
									
										
										
										
											2009-02-25 00:12:36 +00:00
										 |  |  |     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); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-15 11:06:07 +01:00
										 |  |  | Atom | 
					
						
							|  |  |  | Yap_NameOfBinaryOp(int i) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return Yap_LookupAtom(InitBinTab[i].OpName); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-25 00:12:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       Yap_EvalError(RESOURCE_ERROR_HEAP,TermNil,"at InitBinaryExps"); | 
					
						
							| 
									
										
										
										
											2009-05-22 11:21:39 -05:00
										 |  |  |       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); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |