316 lines
6.7 KiB
C
316 lines
6.7 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: eval.c *
|
|
* Last rev: *
|
|
* mods: *
|
|
* comments: arithmetical expression evaluation *
|
|
* *
|
|
*************************************************************************/
|
|
#ifdef SCCS
|
|
static char SccsId[] = "%W% %G%";
|
|
#endif
|
|
|
|
/**
|
|
@file arith0.c
|
|
|
|
@defgroup arithmetic_operators Arithmetic Functions
|
|
@ingroup arithmetic
|
|
|
|
YAP implements several arithmetic functions, they are defined as
|
|
fields in three enumerations, such that there is one enumeration
|
|
per each different arity:
|
|
|
|
- #arith0_op defines constants and arity 0 arithmetic functions
|
|
|
|
@copydoc #arith0_op
|
|
|
|
- #arith1_op defines single argument arithmetic functions
|
|
|
|
@copydoc #arith1_op
|
|
|
|
- #arith2_op defines binary arithmetic functions
|
|
|
|
@copydoc #arith2_op
|
|
|
|
Arithmetic expressions
|
|
in YAP may use the following operators:
|
|
|
|
- <b>pi [ISO]</b><p> @anchor pi_0
|
|
|
|
An approximation to the value of <em>pi</em>, that is, the ratio of a circle's circumference to its diameter.
|
|
|
|
- <b>e</b><p> @anchor e_0
|
|
|
|
Euler's number, the base of the natural logarithms.
|
|
|
|
- <b>epsilon</b><p> @anchor epsilon_0
|
|
|
|
The difference between the float `1.0` and the next largest floating point number.
|
|
|
|
- <b>inf</b><p> @anchor inf_0
|
|
|
|
Infinity according to the IEEE Floating-Point standard. Note that evaluating this term will generate a domain error in the `iso` language mode.
|
|
|
|
Note also that YAP supports `+inf` and `-inf`
|
|
|
|
- <b>nan (not a number)</b><p> @anchor nan_0
|
|
|
|
Not-a-number according to the IEEE Floating-Point standard. Note that evaluating this term will generate a domain error in the `iso` language mode.
|
|
|
|
- <b>random</b><p> @anchor random_0
|
|
|
|
A "random" floating point number between 0 and 1.
|
|
|
|
- <b>cputime</b><p> @anchor cputime_0
|
|
|
|
CPU time since YAP was invoked, in seconds.
|
|
|
|
- <b>heapused</b><p> @anchor heapused_0
|
|
|
|
Heap (data-base) space used, in bytes.
|
|
|
|
- <b>local</b><p> @anchor local_0
|
|
|
|
Local stack in use, in bytes
|
|
|
|
- <b>$b</b><p> @anchor b_0
|
|
|
|
current choicepoint
|
|
|
|
- <b>$env</b><p> @anchor env_0
|
|
|
|
Environment
|
|
|
|
- <b>$tr</b><p> @anchor tr_0
|
|
|
|
Trail in use
|
|
|
|
- <b>$free_stack</b><p> @anchor free_stack_0
|
|
|
|
Amount of free stack space, that is, free space between global and local stacks.
|
|
|
|
- <b>global</b><p> @anchor global_0
|
|
|
|
Global stack in use, in bytes.
|
|
*
|
|
*/
|
|
|
|
#include "Yap.h"
|
|
#include "Yatom.h"
|
|
#include "YapHeap.h"
|
|
#include "eval.h"
|
|
|
|
|
|
#ifndef PI
|
|
#ifdef M_PI
|
|
#define PI M_PI
|
|
#else
|
|
#define PI 3.14159265358979323846
|
|
#endif
|
|
#endif
|
|
|
|
#ifndef M_E
|
|
#define M_E 2.7182818284590452354
|
|
#endif
|
|
|
|
#ifndef INFINITY
|
|
#define INFINITY (1.0/0.0)
|
|
#endif
|
|
|
|
#ifndef NAN
|
|
#define NAN (0.0/0.0)
|
|
#endif
|
|
|
|
/* copied from SWI-Prolog */
|
|
#ifndef DBL_EPSILON /* normal for IEEE 64-bit double */
|
|
#define DBL_EPSILON 0.00000000000000022204
|
|
#endif
|
|
|
|
static Term
|
|
eval0(Int fi) {
|
|
CACHE_REGS
|
|
arith0_op fop = fi;
|
|
switch (fop) {
|
|
case op_pi:
|
|
{
|
|
RFLOAT(PI);
|
|
}
|
|
case op_e:
|
|
{
|
|
RFLOAT(M_E);
|
|
}
|
|
case op_epsilon:
|
|
{
|
|
RFLOAT(DBL_EPSILON);
|
|
}
|
|
case op_inf:
|
|
{
|
|
#ifdef _MSC_VER /* Microsoft's Visual C++ Compiler */
|
|
Yap_Error(TYPE_ERROR_EVALUABLE, TermNil, "evaluating infinity");
|
|
P = (yamop *)FAILCODE;
|
|
RERROR();
|
|
#else
|
|
if (yap_flags[LANGUAGE_MODE_FLAG] == 1) {/* iso */
|
|
Yap_Error(TYPE_ERROR_EVALUABLE, TermNil, "evaluating infinity");
|
|
P = (yamop *)FAILCODE;
|
|
RERROR();
|
|
} else {
|
|
RFLOAT(INFINITY);
|
|
}
|
|
#endif
|
|
}
|
|
case op_nan:
|
|
{
|
|
#ifdef _MSC_VER /* Microsoft's Visual C++ Compi<ler */
|
|
Yap_Error(TYPE_ERROR_EVALUABLE, TermNil, "evaluating infinity");
|
|
P = (yamop *)FAILCODE;
|
|
RERROR();
|
|
#else
|
|
if (yap_flags[LANGUAGE_MODE_FLAG] == 1) {/* iso */
|
|
Yap_Error(TYPE_ERROR_EVALUABLE, TermNil, "evaluating not-a-number");
|
|
P = (yamop *)FAILCODE;
|
|
RERROR();
|
|
} else {
|
|
RFLOAT(NAN);
|
|
}
|
|
#endif
|
|
}
|
|
case op_random:
|
|
{
|
|
RFLOAT(Yap_random());
|
|
}
|
|
case op_cputime:
|
|
{
|
|
RFLOAT((Float)Yap_cputime()/1000.0);
|
|
}
|
|
case op_heapused:
|
|
/// - heapused
|
|
/// Heap (data-base) space used, in bytes.
|
|
///
|
|
RINT(HeapUsed);
|
|
case op_localsp:
|
|
/// - local
|
|
/// Local stack in use, in bytes
|
|
///
|
|
#if YAPOR_SBA
|
|
RINT((Int)ASP);
|
|
#else
|
|
RINT(LCL0 - ASP);
|
|
#endif
|
|
case op_b:
|
|
/// - $b
|
|
/// current choicepoint
|
|
///
|
|
#if YAPOR_SBA
|
|
RINT((Int)B);
|
|
#else
|
|
RINT(LCL0 - (CELL *)B);
|
|
#endif
|
|
case op_env:
|
|
/// - $env
|
|
/// Environment
|
|
///
|
|
#if YAPOR_SBA
|
|
RINT((Int)YENV);
|
|
#else
|
|
RINT(LCL0 - YENV);
|
|
#endif
|
|
case op_tr:
|
|
/// - $tr
|
|
/// Trail in use
|
|
///
|
|
#if YAPOR_SBA
|
|
RINT(TR);
|
|
#else
|
|
RINT(((CELL *)TR)-LCL0);
|
|
#endif
|
|
case op_stackfree:
|
|
/// - $free_stack
|
|
///
|
|
/// Not-a-number according to the IEEE Floating-Point standard. Note that evaluating this term will generate a domain error in the `iso` language mode.
|
|
RINT(Unsigned(ASP) - Unsigned(HR));
|
|
case op_globalsp:
|
|
/// - global
|
|
/// Global stack in use, in bytes.
|
|
///
|
|
#if YAPOR_SBA
|
|
RINT((Int)HR);
|
|
#else
|
|
RINT(HR - H0);
|
|
#endif
|
|
}
|
|
/// end of switch
|
|
RERROR();
|
|
}
|
|
|
|
Term Yap_eval_atom(Int f)
|
|
{
|
|
return eval0(f);
|
|
}
|
|
|
|
typedef struct init_const_eval {
|
|
char *OpName;
|
|
arith0_op f;
|
|
} InitConstEntry;
|
|
|
|
static InitConstEntry InitConstTab[] = {
|
|
{"pi", op_pi},
|
|
{"e", op_e},
|
|
{"epsilon", op_epsilon},
|
|
{"inf", op_inf},
|
|
{"nan", op_nan},
|
|
{"random", op_random},
|
|
{"cputime", op_cputime},
|
|
{"heapused", op_heapused},
|
|
{"local_sp", op_localsp},
|
|
{"global_sp", op_globalsp},
|
|
{"$last_choice_pt", op_b},
|
|
{"$env", op_env},
|
|
{"$tr", op_tr},
|
|
{"stackfree", op_stackfree},
|
|
};
|
|
|
|
void
|
|
Yap_InitConstExps(void)
|
|
{
|
|
unsigned int i;
|
|
ExpEntry *p;
|
|
|
|
for (i = 0; i < sizeof(InitConstTab)/sizeof(InitConstEntry); ++i) {
|
|
AtomEntry *ae = RepAtom(Yap_LookupAtom(InitConstTab[i].OpName));
|
|
if (ae == NULL) {
|
|
Yap_Error(OUT_OF_HEAP_ERROR,TermNil,"at InitConstExps");
|
|
return;
|
|
}
|
|
WRITE_LOCK(ae->ARWLock);
|
|
if (Yap_GetExpPropHavingLock(ae, 0)) {
|
|
WRITE_UNLOCK(ae->ARWLock);
|
|
break;
|
|
}
|
|
p = (ExpEntry *) Yap_AllocAtomSpace(sizeof(ExpEntry));
|
|
p->KindOfPE = ExpProperty;
|
|
p->ArityOfEE = 0;
|
|
p->ENoOfEE = 0;
|
|
p->FOfEE = InitConstTab[i].f;
|
|
AddPropToAtom(ae, (PropEntry *)p);
|
|
WRITE_UNLOCK(ae->ARWLock);
|
|
}
|
|
}
|
|
|
|
/* This routine is called from Restore to make sure we have the same arithmetic operators */
|
|
int
|
|
Yap_ReInitConstExps(void)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
/// @}
|