302 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			302 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/*************************************************************************
							 | 
						||
| 
								 | 
							
								*									 *
							 | 
						||
| 
								 | 
							
								*	 YAP Prolog 							 *
							 | 
						||
| 
								 | 
							
								*									 *
							 | 
						||
| 
								 | 
							
								*	Yap Prolog was developed at NCCUP - Universidade do Porto	 *
							 | 
						||
| 
								 | 
							
								*									 *
							 | 
						||
| 
								 | 
							
								* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997	 *
							 | 
						||
| 
								 | 
							
								*									 *
							 | 
						||
| 
								 | 
							
								**************************************************************************
							 | 
						||
| 
								 | 
							
								*									 *
							 | 
						||
| 
								 | 
							
								* File:		evaltwo.c						 *
							 | 
						||
| 
								 | 
							
								* Last rev:								 *
							 | 
						||
| 
								 | 
							
								* mods:									 *
							 | 
						||
| 
								 | 
							
								* comments:	is/4 predicate						 *
							 | 
						||
| 
								 | 
							
								*									 *
							 | 
						||
| 
								 | 
							
								*************************************************************************/
							 | 
						||
| 
								 | 
							
								#ifdef SCCS
							 | 
						||
| 
								 | 
							
								static char     SccsId[] = "%W% %G%";
							 | 
						||
| 
								 | 
							
								#endif 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * This predicates had to be developed here because of a bug in the MPW
							 | 
						||
| 
								 | 
							
								 * compiler, which was not able to compile the original eval.c 
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "Yap.h"
							 | 
						||
| 
								 | 
							
								#include "Yatom.h"
							 | 
						||
| 
								 | 
							
								#include "Heap.h"
							 | 
						||
| 
								 | 
							
								#include "eval.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define IntRes(X)       return(unify_constant(ARG1,MkIntegerTerm(X)))
							 | 
						||
| 
								 | 
							
								#define FloatRes(X)	return(unify_constant(ARG1,MkEvalFl(X)))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int 
							 | 
						||
| 
								 | 
							
								BinEvalInt(BITS16 op, Int i1, Int i2)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  switch(op) {
							 | 
						||
| 
								 | 
							
								  case e_plus:
							 | 
						||
| 
								 | 
							
								    REvalInt(i1 + i2);
							 | 
						||
| 
								 | 
							
								  case e_dif:
							 | 
						||
| 
								 | 
							
								    REvalInt(i1 - i2);
							 | 
						||
| 
								 | 
							
								  case e_times:
							 | 
						||
| 
								 | 
							
								    REvalInt(i1 * i2);
							 | 
						||
| 
								 | 
							
								  case e_div:
							 | 
						||
| 
								 | 
							
								#ifdef TRY_TO_CONVERT_FLOATS_TO_INTS
							 | 
						||
| 
								 | 
							
								    if (i1 % i2 == 0)
							 | 
						||
| 
								 | 
							
								      REvalInt(i1 / i2);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    REvalFl(FL(i1) / FL(i2));
							 | 
						||
| 
								 | 
							
								  case e_and:
							 | 
						||
| 
								 | 
							
								    REvalInt(i1 & i2);
							 | 
						||
| 
								 | 
							
								  case e_xor:
							 | 
						||
| 
								 | 
							
								    REvalInt(i1 ^ i2);
							 | 
						||
| 
								 | 
							
								  case e_or:
							 | 
						||
| 
								 | 
							
								    REvalInt(i1 | i2);
							 | 
						||
| 
								 | 
							
								  case e_lshift:
							 | 
						||
| 
								 | 
							
								    REvalInt(i1 << i2);
							 | 
						||
| 
								 | 
							
								  case e_rshift:
							 | 
						||
| 
								 | 
							
								    REvalInt(i1 >> i2);
							 | 
						||
| 
								 | 
							
								  case e_mod:
							 | 
						||
| 
								 | 
							
								    REvalInt(i1 % i2);
							 | 
						||
| 
								 | 
							
								  case e_idiv:
							 | 
						||
| 
								 | 
							
								    REvalInt(i1 / i2);
							 | 
						||
| 
								 | 
							
								  case e_gcd:
							 | 
						||
| 
								 | 
							
								    REvalInt(gcd(abs(i1),abs(i2)));
							 | 
						||
| 
								 | 
							
								  case e_gcdmult:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      Int i;
							 | 
						||
| 
								 | 
							
								      REvalInt(gcdmult(abs(i1),abs(i2), &i));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  case e_min:
							 | 
						||
| 
								 | 
							
								    REvalInt((i1 < i2 ? i1 : i2));
							 | 
						||
| 
								 | 
							
								  case e_max:
							 | 
						||
| 
								 | 
							
								    REvalInt((i1 > i2 ? i1 : i2));
							 | 
						||
| 
								 | 
							
								  case e_power:
							 | 
						||
| 
								 | 
							
								    REvalFl(pow(FL(i1), FL(i2)));
							 | 
						||
| 
								 | 
							
								  case e_atan2:
							 | 
						||
| 
								 | 
							
								    REvalFl(atan2(FL(i1), FL(i2)));
							 | 
						||
| 
								 | 
							
								  default:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      Term t, ti[2];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      ti[0] = MkAtomTerm(NameOfFunctor(FunctorOfTerm(current_eval_term)));
							 | 
						||
| 
								 | 
							
								      ti[1] = MkIntegerTerm(2);
							 | 
						||
| 
								 | 
							
								      t = MkApplTerm(MkFunctor(LookupAtom("/"),2), 2, ti);
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_EVALUABLE, t,
							 | 
						||
| 
								 | 
							
									    "in arithmetic expression  %s(%d,%d)",
							 | 
						||
| 
								 | 
							
									    RepAtom(NameOfFunctor(FunctorOfTerm(current_eval_term)))->StrOfAE,
							 | 
						||
| 
								 | 
							
									    i1,
							 | 
						||
| 
								 | 
							
									    i2
							 | 
						||
| 
								 | 
							
									    );
							 | 
						||
| 
								 | 
							
								      P = (yamop *)FAILCODE;
							 | 
						||
| 
								 | 
							
								      REvalError();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int 
							 | 
						||
| 
								 | 
							
								BinEvalFl(BITS16 op, Float f1, Float f2, int flts)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  switch(op) {
							 | 
						||
| 
								 | 
							
								  case e_plus:
							 | 
						||
| 
								 | 
							
								    REvalFl(f1 + f2);
							 | 
						||
| 
								 | 
							
								  case e_dif:
							 | 
						||
| 
								 | 
							
								    REvalFl(f1 - f2);
							 | 
						||
| 
								 | 
							
								  case e_times:
							 | 
						||
| 
								 | 
							
								    REvalFl(f1 * f2);
							 | 
						||
| 
								 | 
							
								  case e_div:
							 | 
						||
| 
								 | 
							
								    REvalFl(f1 / f2);
							 | 
						||
| 
								 | 
							
								  case e_power:
							 | 
						||
| 
								 | 
							
								    REvalFl(pow(f1, f2));
							 | 
						||
| 
								 | 
							
								  case e_atan2:
							 | 
						||
| 
								 | 
							
								    REvalFl(atan2(f1, f2));
							 | 
						||
| 
								 | 
							
								  case e_min:
							 | 
						||
| 
								 | 
							
								    REvalFl((f1 < f2 ? f1 : f2));
							 | 
						||
| 
								 | 
							
								  case e_max:
							 | 
						||
| 
								 | 
							
								    REvalFl((f1 > f2 ? f1 : f2));
							 | 
						||
| 
								 | 
							
								  case e_lshift:
							 | 
						||
| 
								 | 
							
								    if (flts & 1)
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_INTEGER, MkFloatTerm(f1), "<</2");
							 | 
						||
| 
								 | 
							
								    else 
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_INTEGER, MkFloatTerm(f2), "<</2");
							 | 
						||
| 
								 | 
							
								    P = (yamop *)FAILCODE;
							 | 
						||
| 
								 | 
							
								    REvalError();
							 | 
						||
| 
								 | 
							
								  case e_rshift:
							 | 
						||
| 
								 | 
							
								    if (flts & 1)
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_INTEGER, MkFloatTerm(f1), ">>/2");
							 | 
						||
| 
								 | 
							
								    else 
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_INTEGER, MkFloatTerm(f2), ">>/2");
							 | 
						||
| 
								 | 
							
								    P = (yamop *)FAILCODE;
							 | 
						||
| 
								 | 
							
								    REvalError();
							 | 
						||
| 
								 | 
							
								  case e_and:
							 | 
						||
| 
								 | 
							
								    if (flts & 1)
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_INTEGER, MkFloatTerm(f1), "/\\/2");
							 | 
						||
| 
								 | 
							
								    else 
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_INTEGER, MkFloatTerm(f2), "/\\/2");
							 | 
						||
| 
								 | 
							
								    P = (yamop *)FAILCODE;
							 | 
						||
| 
								 | 
							
								    REvalError();
							 | 
						||
| 
								 | 
							
								  case e_xor:
							 | 
						||
| 
								 | 
							
								    if (flts & 1)
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_INTEGER, MkFloatTerm(f1), "#/2");
							 | 
						||
| 
								 | 
							
								    else 
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_INTEGER, MkFloatTerm(f2), "#/2");
							 | 
						||
| 
								 | 
							
								    P = (yamop *)FAILCODE;
							 | 
						||
| 
								 | 
							
								    REvalError();
							 | 
						||
| 
								 | 
							
								  case e_or:
							 | 
						||
| 
								 | 
							
								    if (flts & 1)
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_INTEGER, MkFloatTerm(f1), "\\/ /2");
							 | 
						||
| 
								 | 
							
								    else 
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_INTEGER, MkFloatTerm(f2), "\\/ /2");
							 | 
						||
| 
								 | 
							
								    P = (yamop *)FAILCODE;
							 | 
						||
| 
								 | 
							
								    REvalError();
							 | 
						||
| 
								 | 
							
								  case e_mod:
							 | 
						||
| 
								 | 
							
								    if (flts & 1)
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_INTEGER, MkFloatTerm(f1), "mod/2");
							 | 
						||
| 
								 | 
							
								    else 
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_INTEGER, MkFloatTerm(f2), "mod/2");
							 | 
						||
| 
								 | 
							
								    P = (yamop *)FAILCODE;
							 | 
						||
| 
								 | 
							
								    REvalError();
							 | 
						||
| 
								 | 
							
								  case e_idiv:
							 | 
						||
| 
								 | 
							
								    if (flts & 1)
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_INTEGER, MkFloatTerm(f1), "/ /2");
							 | 
						||
| 
								 | 
							
								    else 
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_INTEGER, MkFloatTerm(f2), "/ /2");
							 | 
						||
| 
								 | 
							
								    P = (yamop *)FAILCODE;
							 | 
						||
| 
								 | 
							
								    REvalError();
							 | 
						||
| 
								 | 
							
								  case e_gcd:
							 | 
						||
| 
								 | 
							
								    if (flts & 1)
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_INTEGER, MkFloatTerm(f1), "gcd/2");
							 | 
						||
| 
								 | 
							
								    else 
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_INTEGER, MkFloatTerm(f2), "gcd/2");
							 | 
						||
| 
								 | 
							
								    P = (yamop *)FAILCODE;
							 | 
						||
| 
								 | 
							
								    REvalError();
							 | 
						||
| 
								 | 
							
								  case e_gcdmult:
							 | 
						||
| 
								 | 
							
								    if (flts & 1)
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_INTEGER, MkFloatTerm(f1), "gcdmult/2");
							 | 
						||
| 
								 | 
							
								    else 
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_INTEGER, MkFloatTerm(f2), "gcdmult/2");
							 | 
						||
| 
								 | 
							
								    P = (yamop *)FAILCODE;
							 | 
						||
| 
								 | 
							
								    REvalError();
							 | 
						||
| 
								 | 
							
								  default:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      Term t, ti[2];
							 | 
						||
| 
								 | 
							
								      
							 | 
						||
| 
								 | 
							
								      ti[0] = MkAtomTerm(NameOfFunctor(FunctorOfTerm(current_eval_term)));
							 | 
						||
| 
								 | 
							
								      ti[1] = MkIntegerTerm(2);
							 | 
						||
| 
								 | 
							
								      t = MkApplTerm(MkFunctor(LookupAtom("/"),2), 2, ti);
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_EVALUABLE, t,
							 | 
						||
| 
								 | 
							
									    "in arithmetic expression %s(%d,%d)",
							 | 
						||
| 
								 | 
							
									    RepAtom(NameOfFunctor(FunctorOfTerm(current_eval_term)))->StrOfAE,
							 | 
						||
| 
								 | 
							
									    f1,
							 | 
						||
| 
								 | 
							
									    f2
							 | 
						||
| 
								 | 
							
									    );
							 | 
						||
| 
								 | 
							
								      P = (yamop *)FAILCODE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    REvalError();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Int
							 | 
						||
| 
								 | 
							
								p_binary_is(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  register BITS16 OpNum;
							 | 
						||
| 
								 | 
							
								  Term t2,t3,t4;
							 | 
						||
| 
								 | 
							
								  Int i1;
							 | 
						||
| 
								 | 
							
								  Float f1;
							 | 
						||
| 
								 | 
							
								  int flag;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  current_eval_term = MkIntTerm(2);
							 | 
						||
| 
								 | 
							
								  t2 = Deref(ARG2);
							 | 
						||
| 
								 | 
							
								  if (IsVarTerm(t2)) {
							 | 
						||
| 
								 | 
							
								    Error(INSTANTIATION_ERROR, t2, "operation for is/4");
							 | 
						||
| 
								 | 
							
								    P = (yamop *)FAILCODE;
							 | 
						||
| 
								 | 
							
								    return(FALSE);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  if (IsIntTerm(t2))
							 | 
						||
| 
								 | 
							
								    OpNum = IntOfTerm(t2);
							 | 
						||
| 
								 | 
							
								  else if (IsAtomTerm(t2)) {
							 | 
						||
| 
								 | 
							
								    Atom            name = AtomOfTerm(t2);
							 | 
						||
| 
								 | 
							
								    Prop            p;
							 | 
						||
| 
								 | 
							
								    if ((p = GetExpProp(name, 2)) == NIL) {
							 | 
						||
| 
								 | 
							
								      Term t, ti[2];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      ti[0] = MkIntegerTerm(2);
							 | 
						||
| 
								 | 
							
								      ti[0] = MkAtomTerm(name);
							 | 
						||
| 
								 | 
							
								      t = MkApplTerm(MkFunctor(LookupAtom("/"),2), 2, ti);
							 | 
						||
| 
								 | 
							
								      Error(TYPE_ERROR_EVALUABLE, t,
							 | 
						||
| 
								 | 
							
									    "arithmetic expression %s/%d",
							 | 
						||
| 
								 | 
							
									    RepAtom(name)->StrOfAE,
							 | 
						||
| 
								 | 
							
									    2
							 | 
						||
| 
								 | 
							
									    );
							 | 
						||
| 
								 | 
							
								      P = (yamop *)FAILCODE;
							 | 
						||
| 
								 | 
							
								      return(FALSE);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    OpNum = RepExpProp(p)->ENoOfEE;
							 | 
						||
| 
								 | 
							
								  } else
							 | 
						||
| 
								 | 
							
								    return (FALSE);
							 | 
						||
| 
								 | 
							
								  t3 = Deref(ARG3);
							 | 
						||
| 
								 | 
							
								  t4 = Deref(ARG4);
							 | 
						||
| 
								 | 
							
								  if (IsVarTerm(t3) || IsVarTerm(t4)) {
							 | 
						||
| 
								 | 
							
								    int op = 0;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    while (InitTab[op].eno != OpNum) op++;
							 | 
						||
| 
								 | 
							
								    Error(INSTANTIATION_ERROR, (IsVarTerm(t3) ? t3 : t4),
							 | 
						||
| 
								 | 
							
									  "arithmetic expression %s/2", InitTab[op].OpName);
							 | 
						||
| 
								 | 
							
								    return(FALSE);
							 | 
						||
| 
								 | 
							
								  } 
							 | 
						||
| 
								 | 
							
								  if (IsIntegerTerm(t3)) {
							 | 
						||
| 
								 | 
							
								    i1 = IntegerOfTerm(t3);
							 | 
						||
| 
								 | 
							
								  t3_int:
							 | 
						||
| 
								 | 
							
								    if (IsIntegerTerm(t4)) {
							 | 
						||
| 
								 | 
							
								      flag = BinEvalInt(OpNum, i1, IntegerOfTerm(t4));
							 | 
						||
| 
								 | 
							
								    } else if (IsFloatTerm(t4)) {
							 | 
						||
| 
								 | 
							
								      flag = BinEvalFl(OpNum, FL(i1), FloatOfTerm(t4), 2);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      int aflag = Eval(t4);
							 | 
						||
| 
								 | 
							
								      if (aflag == FError) {
							 | 
						||
| 
								 | 
							
									return(FALSE);
							 | 
						||
| 
								 | 
							
								      } else if (aflag == FInt) {
							 | 
						||
| 
								 | 
							
									flag = BinEvalInt(OpNum, i1, eval_int);
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
									flag = BinEvalFl(OpNum, FL(i1), eval_flt, 2);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } else if (IsFloatTerm(t3)) {
							 | 
						||
| 
								 | 
							
								    f1 = FloatOfTerm(t3);
							 | 
						||
| 
								 | 
							
								  t3_flt:
							 | 
						||
| 
								 | 
							
								    if (IsIntegerTerm(t4)) {
							 | 
						||
| 
								 | 
							
								      flag = BinEvalFl(OpNum, f1, FL(IntegerOfTerm(t4)), 1);
							 | 
						||
| 
								 | 
							
								    } else if (IsFloatTerm(t4)) {
							 | 
						||
| 
								 | 
							
								      flag = BinEvalFl(OpNum, f1, FloatOfTerm(t4), 3);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      int aflag = Eval(t4);
							 | 
						||
| 
								 | 
							
								      if (aflag == FError) {
							 | 
						||
| 
								 | 
							
									return(FALSE);
							 | 
						||
| 
								 | 
							
								      } else if (aflag == FInt) {
							 | 
						||
| 
								 | 
							
									flag = BinEvalFl(OpNum, f1, eval_int, 1);
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
									flag = BinEvalFl(OpNum, f1, eval_flt, 3);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    int aflag = Eval(t3);
							 | 
						||
| 
								 | 
							
								    if (aflag == FError) {
							 | 
						||
| 
								 | 
							
								      return(FALSE);
							 | 
						||
| 
								 | 
							
								    } else if (aflag == FInt) {
							 | 
						||
| 
								 | 
							
								      i1 = eval_int;
							 | 
						||
| 
								 | 
							
								      goto t3_int;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      f1 = eval_flt;
							 | 
						||
| 
								 | 
							
								      goto t3_flt;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  if (flag == FError) {
							 | 
						||
| 
								 | 
							
								    return(FALSE);
							 | 
						||
| 
								 | 
							
								  } else if (flag == FInt) {
							 | 
						||
| 
								 | 
							
								    return(unify_constant(ARG1,MkIntegerTerm(eval_int)));
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    return(unify_constant(ARG1,MkFloatTerm(eval_flt)));    
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 |