This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/H/TermExt.h
2005-11-23 03:01:33 +00:00

572 lines
11 KiB
C

/*************************************************************************
* *
* YAP Prolog %W% %G% *
* Yap Prolog was developed at NCCUP - Universidade do Porto *
* *
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
* *
**************************************************************************
* *
* File: TermExt.h *
* mods: *
* comments: Extensions to standard terms for YAP *
* version: $Id: TermExt.h,v 1.3 2005-11-23 03:01:33 vsc Exp $ *
*************************************************************************/
#ifdef USE_SYSTEM_MALLOC
#define SF_STORE (&(Yap_heap_regs->funcs))
#else
#define SF_STORE ((special_functors *)HEAP_INIT_BASE)
#endif
#if USE_OFFSETS
#define AtomFoundVar ((Atom)(&(((special_functors *)(NULL))->AtFoundVar)))
#define AtomFreeTerm ((Atom)(&(((special_functors *)(NULL))->AtFreeTerm)))
#define AtomNil ((Atom)(&(((special_functors *)(NULL))->AtNil)))
#define AtomDot ((Atom)(&(((special_functors *)(NULL))->AtDot)))
#elif THREADS
#define AtomFoundVar AbsAtom(SF_STORE->AtFoundVar)
#define AtomFreeTerm AbsAtom(SF_STORE->AtFreeTerm)
#define AtomNil AbsAtom(SF_STORE->AtNil)
#define AtomDot AbsAtom(SF_STORE->AtDot)
#else
#define AtomFoundVar AbsAtom(&(SF_STORE->AtFoundVar))
#define AtomFreeTerm AbsAtom(&(SF_STORE->AtFreeTerm))
#define AtomNil AbsAtom(&(SF_STORE->AtNil))
#define AtomDot AbsAtom(&(SF_STORE->AtDot))
#endif
#define TermFoundVar MkAtomTerm(AtomFoundVar)
#define TermFreeTerm MkAtomTerm(AtomFreeTerm)
#define TermNil MkAtomTerm(AtomNil)
#define TermDot MkAtomTerm(AtomDot)
#if defined(IN_SECOND_QUADRANT) && !GC_NO_TAGS
typedef enum
{
db_ref_e = sizeof (Functor *) | RBIT,
long_int_e = 2 * sizeof (Functor *) | RBIT,
#ifdef USE_GMP
big_int_e = 3 * sizeof (Functor *) | RBIT,
double_e = 4 * sizeof (Functor *) | RBIT
#else
double_e = 3 * sizeof (Functor *) | RBIT
#endif
}
blob_type;
#else
typedef enum
{
db_ref_e = sizeof (Functor *),
long_int_e = 2 * sizeof (Functor *),
#ifdef USE_GMP
big_int_e = 3 * sizeof (Functor *),
double_e = 4 * sizeof (Functor *)
#else
double_e = 3 * sizeof (Functor *)
#endif
}
blob_type;
#endif
#define FunctorDBRef ((Functor)(db_ref_e))
#define FunctorLongInt ((Functor)(long_int_e))
#ifdef USE_GMP
#define FunctorBigInt ((Functor)(big_int_e))
#endif
#define FunctorDouble ((Functor)(double_e))
#define EndSpecials (double_e)
inline EXTERN blob_type BlobOfFunctor (Functor f);
inline EXTERN blob_type
BlobOfFunctor (Functor f)
{
return (blob_type) ((CELL) f);
}
#ifdef COROUTINING
typedef struct
{
/* what to do when someone tries to bind our term to someone else
in some predefined context */
void (*bind_op) (Term *, Term);
/* what to do if someone wants to copy our constraint */
int (*copy_term_op) (CELL *, CELL ***, CELL *);
/* copy the constraint into a term and back */
Term (*to_term_op) (CELL *);
int (*term_to_op) (Term, Term);
/* op called to do marking in GC */
void (*mark_op) (CELL *);
} ext_op;
/* known delays */
typedef enum
{
empty_ext = 0 * sizeof (ext_op), /* default op, this should never be called */
attvars_ext = 1 * sizeof (ext_op) /* support for attributed variables */
/* add your own extensions here */
/* keep this one */
}
exts;
/* array with the ops for your favourite extensions */
extern ext_op attas[attvars_ext + 1];
#endif
/* make sure that these data structures are the first thing to be allocated
in the heap when we start the system */
#if THREADS
typedef struct special_functors_struct
{
AtomEntry *AtFoundVar;
AtomEntry *AtFreeTerm;
AtomEntry *AtNil;
AtomEntry *AtDot;
} special_functors;
#else
typedef struct special_functors_struct
{
AtomEntry AtFoundVar;
char AtFoundVarChars[8];
AtomEntry AtFreeTerm;
char AtFreeTermChars[8];
AtomEntry AtNil;
char AtNilChars[8];
AtomEntry AtDot;
char AtDotChars[8];
}
special_functors;
#endif
#if USE_SYSTEM_MALLOC
#define MAX_SPECIALS_TAG (4*4096)
#else
#define MAX_SPECIALS_TAG ((CELL)AtomBase)
#endif
#if SIZEOF_DOUBLE == SIZEOF_LONG_INT
#if GC_NO_TAGS
inline EXTERN Term MkFloatTerm (Float);
inline EXTERN Term
MkFloatTerm (Float dbl)
{
return (Term) ((H[0] = (CELL) FunctorDouble, *(Float *) (H + 1) =
dbl, H[2] = (2 * sizeof (CELL) + EndSpecials), H +=
3, AbsAppl (H - 3)));
}
#else
inline EXTERN Term MkFloatTerm (Float);
inline EXTERN Term
MkFloatTerm (Float dbl)
{
return (Term) ((H[0] = (CELL) FunctorDouble, *(Float *) (H + 1) =
dbl, H[2] = ((2 * sizeof (CELL) + EndSpecials) | MBIT), H +=
3, AbsAppl (H - 3)));
}
#endif
inline EXTERN Float FloatOfTerm (Term t);
inline EXTERN Float
FloatOfTerm (Term t)
{
return (Float) (*(Float *) (RepAppl (t) + 1));
}
#define InitUnalignedFloat()
#else
#if SIZEOF_DOUBLE == 2*SIZEOF_LONG_INT
inline EXTERN Float STD_PROTO (CpFloatUnaligned, (CELL *));
inline EXTERN void STD_PROTO (AlignGlobalForDouble, (void));
#define DOUBLE_ALIGNED(ADDR) ((CELL)(ADDR) & 0x4)
#ifdef i386
inline EXTERN Float
CpFloatUnaligned (CELL * ptr)
{
return *((Float *) (ptr + 1));
}
#else
/* first, need to address the alignment problem */
inline EXTERN Float
CpFloatUnaligned (CELL * ptr)
{
union
{
Float f;
CELL d[2];
} u;
u.d[0] = ptr[1];
u.d[1] = ptr[2];
return (u.f);
}
#endif
#if GC_NO_TAGS
inline EXTERN Term MkFloatTerm (Float);
inline EXTERN Term
MkFloatTerm (Float dbl)
{
return (Term) ((AlignGlobalForDouble (), H[0] =
(CELL) FunctorDouble, *(Float *) (H + 1) = dbl, H[3] =
(3 * sizeof (CELL) + EndSpecials), H +=
4, AbsAppl (H - 4)));
}
#else
inline EXTERN Term MkFloatTerm (Float);
inline EXTERN Term
MkFloatTerm (Float dbl)
{
return (Term) ((AlignGlobalForDouble (), H[0] =
(CELL) FunctorDouble, *(Float *) (H + 1) = dbl, H[3] =
((3 * sizeof (CELL) + EndSpecials) | MBIT), H +=
4, AbsAppl (H - 4)));
}
#endif
inline EXTERN Float FloatOfTerm (Term t);
inline EXTERN Float
FloatOfTerm (Term t)
{
return (Float) ((DOUBLE_ALIGNED (RepAppl (t)) ? *(Float *) (RepAppl (t) + 1)
: CpFloatUnaligned (RepAppl (t))));
}
/* no alignment problems for 64 bit machines */
#else
/* OOPS, YAP only understands Floats that are as large as cells or that
take two cells!!! */
#endif
#endif
inline EXTERN int IsFloatTerm (Term);
inline EXTERN int
IsFloatTerm (Term t)
{
return (int) (IsApplTerm (t) && FunctorOfTerm (t) == FunctorDouble);
}
/* extern Functor FunctorLongInt; */
#if GC_NO_TAGS
inline EXTERN Term MkLongIntTerm (Int);
inline EXTERN Term
MkLongIntTerm (Int i)
{
return (Term) ((H[0] = (CELL) FunctorLongInt, H[1] = (CELL) (i), H[2] =
(2 * sizeof (CELL) + EndSpecials), H +=
3, AbsAppl (H - 3)));
}
#else
inline EXTERN Term MkLongIntTerm (Int);
inline EXTERN Term
MkLongIntTerm (Int i)
{
return (Term) ((H[0] = (CELL) FunctorLongInt, H[1] = (CELL) (i), H[2] =
((2 * sizeof (CELL) + EndSpecials) | MBIT), H +=
3, AbsAppl (H - 3)));
}
#endif
inline EXTERN Int LongIntOfTerm (Term t);
inline EXTERN Int
LongIntOfTerm (Term t)
{
return (Int) (RepAppl (t)[1]);
}
inline EXTERN int IsLongIntTerm (Term);
inline EXTERN int
IsLongIntTerm (Term t)
{
return (int) (IsApplTerm (t) && FunctorOfTerm (t) == FunctorLongInt);
}
#ifdef USE_GMP
#include <stdio.h>
#include <gmp.h>
MP_INT *STD_PROTO (Yap_PreAllocBigNum, (void));
MP_INT *STD_PROTO (Yap_InitBigNum, (Int));
Term STD_PROTO (Yap_MkBigIntTerm, (MP_INT *));
MP_INT *STD_PROTO (Yap_BigIntOfTerm, (Term));
void STD_PROTO (Yap_CleanBigNum, (void));
inline EXTERN int IsBigIntTerm (Term);
inline EXTERN int
IsBigIntTerm (Term t)
{
return (int) (IsApplTerm (t) && FunctorOfTerm (t) == FunctorBigInt);
}
inline EXTERN int IsLargeIntTerm (Term);
inline EXTERN int
IsLargeIntTerm (Term t)
{
return (int) (IsApplTerm (t)
&& ((FunctorOfTerm (t) <= FunctorBigInt)
&& (FunctorOfTerm (t) >= FunctorLongInt)));
}
#else
inline EXTERN int IsBigIntTerm (Term);
inline EXTERN int
IsBigIntTerm (Term t)
{
return (int) (FALSE);
}
inline EXTERN int IsLargeIntTerm (Term);
inline EXTERN int
IsLargeIntTerm (Term t)
{
return (int) (IsApplTerm (t) && FunctorOfTerm (t) == FunctorLongInt);
}
#endif
/* extern Functor FunctorLongInt; */
inline EXTERN int IsLargeNumTerm (Term);
inline EXTERN int
IsLargeNumTerm (Term t)
{
return (int) (IsApplTerm (t)
&& ((FunctorOfTerm (t) <= FunctorDouble)
&& (FunctorOfTerm (t) >= FunctorLongInt)));
}
inline EXTERN int IsNumTerm (Term);
inline EXTERN int
IsNumTerm (Term t)
{
return (int) ((IsIntTerm (t) || IsLargeNumTerm (t)));
}
inline EXTERN Int IsAtomicTerm (Term);
inline EXTERN Int
IsAtomicTerm (Term t)
{
return (Int) (IsAtomOrIntTerm (t) || IsLargeNumTerm (t));
}
inline EXTERN Int IsExtensionFunctor (Functor);
inline EXTERN Int
IsExtensionFunctor (Functor f)
{
return (Int) (f <= FunctorDouble);
}
inline EXTERN Int IsBlobFunctor (Functor);
inline EXTERN Int
IsBlobFunctor (Functor f)
{
return (Int) ((f <= FunctorDouble && f >= FunctorDBRef));
}
inline EXTERN Int IsPrimitiveTerm (Term);
inline EXTERN Int
IsPrimitiveTerm (Term t)
{
return (Int) ((IsAtomOrIntTerm (t)
|| (IsApplTerm (t) && IsBlobFunctor (FunctorOfTerm (t)))));
}
#ifdef TERM_EXTENSIONS
inline EXTERN Int IsAttachFunc (Functor);
inline EXTERN Int
IsAttachFunc (Functor f)
{
return (Int) (FALSE);
}
inline EXTERN Int IsAttachedTerm (Term);
inline EXTERN Int
IsAttachedTerm (Term t)
{
return (Int) ((IsVarTerm (t) && VarOfTerm (t) < H0));
}
inline EXTERN Int SafeIsAttachedTerm (Term);
inline EXTERN Int
SafeIsAttachedTerm (Term t)
{
return (Int) ((IsVarTerm (t) && VarOfTerm (t) < H0
&& VarOfTerm (t) >= (CELL *) Yap_GlobalBase));
}
inline EXTERN exts ExtFromCell (CELL *);
inline EXTERN exts
ExtFromCell (CELL * pt)
{
return attvars_ext;
}
#else
inline EXTERN Int IsAttachFunc (Functor);
inline EXTERN Int
IsAttachFunc (Functor f)
{
return (Int) (FALSE);
}
inline EXTERN Int IsAttachedTerm (Term);
inline EXTERN Int
IsAttachedTerm (Term t)
{
return (Int) (FALSE);
}
#endif
inline EXTERN int STD_PROTO (unify_extension, (Functor, CELL, CELL *, CELL));
EXTERN int STD_PROTO (unify_extension, (Functor, CELL, CELL *, CELL));
inline EXTERN int
unify_extension (Functor f, CELL d0, CELL * pt0, CELL d1)
{
switch (BlobOfFunctor (f))
{
case db_ref_e:
return (d0 == d1);
case long_int_e:
return (pt0[1] == RepAppl (d1)[1]);
#ifdef USE_GMP
case big_int_e:
return (mpz_cmp (Yap_BigIntOfTerm (d0), Yap_BigIntOfTerm (d1)) == 0);
#endif /* USE_GMP */
case double_e:
{
CELL *pt1 = RepAppl (d1);
return (pt0[1] == pt1[1]
#if SIZEOF_DOUBLE == 2*SIZEOF_LONG_INT
&& pt0[2] == pt1[2]
#endif
);
}
}
return (FALSE);
}