| 
									
										
										
										
											2001-04-09 19:54:03 +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:		eval.c							 * | 
					
						
							|  |  |  | * Last rev:								 * | 
					
						
							|  |  |  | * mods:									 * | 
					
						
							|  |  |  | * comments:	arithmetical expression evaluation			 * | 
					
						
							|  |  |  | *									 * | 
					
						
							|  |  |  | *************************************************************************/ | 
					
						
							|  |  |  | #ifdef SCCS
 | 
					
						
							|  |  |  | static char     SccsId[] = "%W% %G%"; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * This file implements arithmetic operations  | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #include "Yap.h"
 | 
					
						
							|  |  |  | #include "Yatom.h"
 | 
					
						
							|  |  |  | #include "Heap.h"
 | 
					
						
							|  |  |  | #include "eval.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  | yap_error_number Yap_matherror = YAP_NO_ERROR; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define E_FUNC   blob_type
 | 
					
						
							|  |  |  | #define E_ARGS   arith_retptr o
 | 
					
						
							|  |  |  | #define USE_E_ARGS   o
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  | #define TMP_BIG()   ((o)->big)
 | 
					
						
							|  |  |  | #define RBIG(v)     return(big_int_e)
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #define RINT(v)     (o)->Int = v; return(long_int_e)
 | 
					
						
							|  |  |  | #define RFLOAT(v)   (o)->dbl = v; return(double_e)
 | 
					
						
							|  |  |  | #define RERROR()    return(db_ref_e)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Term | 
					
						
							|  |  |  | EvalToTerm(blob_type bt, union arith_ret *res) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   switch (bt) { | 
					
						
							|  |  |  |   case long_int_e: | 
					
						
							| 
									
										
										
										
											2006-01-18 15:34:54 +00:00
										 |  |  |     return MkIntegerTerm(res->Int); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   case double_e: | 
					
						
							| 
									
										
										
										
											2006-01-18 15:34:54 +00:00
										 |  |  |     return MkFloatTerm(res->dbl); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef USE_GMP
 | 
					
						
							|  |  |  |   case big_int_e: | 
					
						
							| 
									
										
										
										
											2006-01-18 15:34:54 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |       Term t = Yap_MkBigIntTerm(res->big); | 
					
						
							|  |  |  |       mpz_clear(res->big); | 
					
						
							|  |  |  |       return t; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |   default: | 
					
						
							| 
									
										
										
										
											2006-01-18 15:34:54 +00:00
										 |  |  |     return TermNil; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-11-11 17:38:10 +00:00
										 |  |  | static E_FUNC | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | Eval(Term t, E_ARGS) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (IsVarTerm(t)) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     Yap_Error(INSTANTIATION_ERROR,TermNil,"in arithmetic"); | 
					
						
							| 
									
										
										
										
											2002-11-11 17:38:10 +00:00
										 |  |  |     P = (yamop *)FAILCODE; | 
					
						
							|  |  |  |     RERROR(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (IsApplTerm(t)) { | 
					
						
							|  |  |  |     Functor fun = FunctorOfTerm(t); | 
					
						
							|  |  |  |     switch ((CELL)fun) { | 
					
						
							|  |  |  |     case (CELL)FunctorLongInt: | 
					
						
							|  |  |  |       RINT(LongIntOfTerm(t)); | 
					
						
							|  |  |  |     case (CELL)FunctorDouble: | 
					
						
							|  |  |  |       RFLOAT(FloatOfTerm(t)); | 
					
						
							|  |  |  | #ifdef USE_GMP
 | 
					
						
							|  |  |  |     case (CELL)FunctorBigInt: | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |       { | 
					
						
							|  |  |  | 	MP_INT *new = TMP_BIG(); | 
					
						
							|  |  |  | 	mpz_init_set(new, Yap_BigIntOfTerm(t)); | 
					
						
							|  |  |  | 	RBIG(new); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2002-11-11 17:38:10 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Int n = ArityOfFunctor(fun); | 
					
						
							|  |  |  | 	Atom name  = NameOfFunctor(fun); | 
					
						
							|  |  |  | 	ExpEntry *p; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  | 	if (EndOfPAEntr(p = RepExpProp(Yap_GetExpProp(name, n)))) { | 
					
						
							| 
									
										
										
										
											2002-11-11 17:38:10 +00:00
										 |  |  | 	  Term ti[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	  /* error */ | 
					
						
							|  |  |  | 	  ti[0] = t; | 
					
						
							|  |  |  | 	  ti[1] = MkIntegerTerm(n); | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  | 	  t = Yap_MkApplTerm(Yap_MkFunctor(Yap_LookupAtom("/"),2), 2, ti); | 
					
						
							|  |  |  | 	  Yap_Error(TYPE_ERROR_EVALUABLE, t, | 
					
						
							| 
									
										
										
										
											2002-11-11 17:38:10 +00:00
										 |  |  | 		"functor %s/%d for arithmetic expression", | 
					
						
							|  |  |  | 		RepAtom(name)->StrOfAE,n); | 
					
						
							|  |  |  | 	  P = (yamop *)FAILCODE; | 
					
						
							|  |  |  | 	  RERROR(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (n == 1) | 
					
						
							|  |  |  | 	  return(p->FOfEE.unary(ArgOfTerm(1,t), USE_E_ARGS)); | 
					
						
							|  |  |  | 	return(p->FOfEE.binary(ArgOfTerm(1,t),ArgOfTerm(2,t), USE_E_ARGS)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else if (IsPairTerm(t)) { | 
					
						
							|  |  |  |     return(Eval(HeadOfTerm(t), USE_E_ARGS)); | 
					
						
							|  |  |  |   } else if (IsIntTerm(t)) { | 
					
						
							|  |  |  |     RINT(IntOfTerm(t)); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     Atom name = AtomOfTerm(t); | 
					
						
							|  |  |  |     ExpEntry *p; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     if (EndOfPAEntr(p = RepExpProp(Yap_GetExpProp(name, 0)))) { | 
					
						
							| 
									
										
										
										
											2007-06-04 12:28:02 +00:00
										 |  |  |       Term ti[2], terror; | 
					
						
							|  |  |  |        | 
					
						
							| 
									
										
										
										
											2002-11-11 17:38:10 +00:00
										 |  |  |       /* error */ | 
					
						
							| 
									
										
										
										
											2007-06-04 12:28:02 +00:00
										 |  |  |       ti[0] = t; | 
					
						
							|  |  |  |       ti[1] = MkIntegerTerm(0); | 
					
						
							|  |  |  |       /* error */ | 
					
						
							|  |  |  |       terror = Yap_MkApplTerm(Yap_MkFunctor(Yap_LookupAtom("/"),2), 2, ti); | 
					
						
							|  |  |  |       Yap_Error(TYPE_ERROR_EVALUABLE, terror, | 
					
						
							| 
									
										
										
										
											2002-11-11 17:38:10 +00:00
										 |  |  | 	    "atom %s for arithmetic expression", | 
					
						
							|  |  |  | 	    RepAtom(name)->StrOfAE); | 
					
						
							|  |  |  |       P = (yamop *)FAILCODE; | 
					
						
							|  |  |  |       RERROR(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return(p->FOfEE.constant(USE_E_ARGS)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | E_FUNC | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  | Yap_Eval(Term t, E_ARGS) | 
					
						
							| 
									
										
										
										
											2002-11-11 17:38:10 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   if (IsVarTerm(t)) { | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     Yap_Error(INSTANTIATION_ERROR,TermNil,"in arithmetic"); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     P = (yamop *)FAILCODE; | 
					
						
							|  |  |  |     RERROR(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (IsApplTerm(t)) { | 
					
						
							|  |  |  |     Functor fun = FunctorOfTerm(t); | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     switch ((CELL)fun) { | 
					
						
							|  |  |  |     case (CELL)FunctorLongInt: | 
					
						
							|  |  |  |       RINT(LongIntOfTerm(t)); | 
					
						
							|  |  |  |     case (CELL)FunctorDouble: | 
					
						
							|  |  |  |       RFLOAT(FloatOfTerm(t)); | 
					
						
							|  |  |  | #ifdef USE_GMP
 | 
					
						
							|  |  |  |     case (CELL)FunctorBigInt: | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |       { | 
					
						
							|  |  |  | 	MP_INT *new = TMP_BIG(); | 
					
						
							|  |  |  | 	mpz_init_set(new, Yap_BigIntOfTerm(t)); | 
					
						
							|  |  |  | 	RBIG(new); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	Int n = ArityOfFunctor(fun); | 
					
						
							|  |  |  | 	Atom name  = NameOfFunctor(fun); | 
					
						
							|  |  |  | 	ExpEntry *p; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  | 	if (EndOfPAEntr(p = RepExpProp(Yap_GetExpProp(name, n)))) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 	  Term ti[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	  /* error */ | 
					
						
							|  |  |  | 	  ti[0] = t; | 
					
						
							|  |  |  | 	  ti[1] = MkIntegerTerm(n); | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  | 	  t = Yap_MkApplTerm(Yap_MkFunctor(Yap_LookupAtom("/"),2), 2, ti); | 
					
						
							|  |  |  | 	  Yap_Error(TYPE_ERROR_EVALUABLE, t, | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 		"functor %s/%d for arithmetic expression", | 
					
						
							|  |  |  | 		RepAtom(name)->StrOfAE,n); | 
					
						
							|  |  |  | 	  P = (yamop *)FAILCODE; | 
					
						
							|  |  |  | 	  RERROR(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (n == 1) | 
					
						
							|  |  |  | 	  return(p->FOfEE.unary(ArgOfTerm(1,t), USE_E_ARGS)); | 
					
						
							|  |  |  | 	return(p->FOfEE.binary(ArgOfTerm(1,t),ArgOfTerm(2,t), USE_E_ARGS)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else if (IsPairTerm(t)) { | 
					
						
							|  |  |  |     return(Eval(HeadOfTerm(t), USE_E_ARGS)); | 
					
						
							|  |  |  |   } else if (IsIntTerm(t)) { | 
					
						
							|  |  |  |     RINT(IntOfTerm(t)); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     Atom name = AtomOfTerm(t); | 
					
						
							|  |  |  |     ExpEntry *p; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |     if (EndOfPAEntr(p = RepExpProp(Yap_GetExpProp(name, 0)))) { | 
					
						
							| 
									
										
										
										
											2007-06-04 12:28:02 +00:00
										 |  |  |       Term ti[2], terror; | 
					
						
							|  |  |  |        | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       /* error */ | 
					
						
							| 
									
										
										
										
											2007-06-04 12:28:02 +00:00
										 |  |  |       ti[0] = t; | 
					
						
							|  |  |  |       ti[1] = MkIntegerTerm(0); | 
					
						
							|  |  |  |       /* error */ | 
					
						
							|  |  |  |       terror = Yap_MkApplTerm(Yap_MkFunctor(Yap_LookupAtom("/"),2), 2, ti); | 
					
						
							|  |  |  |       Yap_Error(TYPE_ERROR_EVALUABLE, terror, | 
					
						
							|  |  |  | 	      "atom %s for arithmetic expression", | 
					
						
							|  |  |  | 	      RepAtom(name)->StrOfAE); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       P = (yamop *)FAILCODE; | 
					
						
							|  |  |  |       RERROR(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return(p->FOfEE.constant(USE_E_ARGS)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-08 22:06:45 +00:00
										 |  |  | #ifdef BEAM
 | 
					
						
							|  |  |  | Int BEAM_is(void); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Int | 
					
						
							|  |  |  | BEAM_is(void) | 
					
						
							|  |  |  | {				/* X is Y	 */ | 
					
						
							|  |  |  |   union arith_ret res; | 
					
						
							|  |  |  |   blob_type bt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bt = Eval(Deref(XREGS[2]), &res); | 
					
						
							|  |  |  |   if (bt==db_ref_e) return (NULL); | 
					
						
							|  |  |  |   return (EvalToTerm(bt,&res)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | p_is(void) | 
					
						
							|  |  |  | {				/* X is Y	 */ | 
					
						
							|  |  |  |   union arith_ret res; | 
					
						
							|  |  |  |   blob_type bt; | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |   Term out; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   bt = Eval(Deref(ARG2), &res); | 
					
						
							| 
									
										
										
										
											2006-01-02 02:16:19 +00:00
										 |  |  |   out = EvalToTerm(bt,&res); | 
					
						
							|  |  |  |   if (out == TermNil) { | 
					
						
							|  |  |  |     Yap_Error(EVALUATION_ERROR_INT_OVERFLOW, ARG2, "is/2"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return Yap_unify_constant(ARG1,out); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  | Yap_InitEval(void) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   /* here are the arithmetical predicates */ | 
					
						
							| 
									
										
										
										
											2002-11-18 18:18:05 +00:00
										 |  |  |   Yap_InitConstExps(); | 
					
						
							|  |  |  |   Yap_InitUnaryExps(); | 
					
						
							|  |  |  |   Yap_InitBinaryExps(); | 
					
						
							|  |  |  |   Yap_InitCPred("is", 2, p_is, TestPredFlag | SafePredFlag); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 |