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/CXX/yapt.hh

562 lines
16 KiB
C++
Raw Normal View History

2017-03-20 15:52:48 +00:00
/**
2017-04-07 23:10:59 +01:00
* @file yapt.hh
*/
/**
2017-03-20 15:52:48 +00:00
* @defgroup yap-cplus-term-handling Term Handling in the YAP interface.
*
2017-04-07 23:10:59 +01:00
* @{
*
2017-03-20 15:52:48 +00:00
* @ingroup yap-cplus-interface
2017-04-07 23:10:59 +01:00
* @tableofcontents
2017-03-20 15:52:48 +00:00
*
*
2017-04-07 23:10:59 +01:00
* These classes offer term construction and access. Terms are seens
* as objects that inherit from a virtual class, Currently, all
2017-05-02 07:38:23 +01:00
* terms must reside in the stack and may be moved around during
2017-04-07 23:10:59 +01:00
* garbage collection. Term objects use an handle, in the SWI-Prolog style.
2017-03-20 15:52:48 +00:00
*
2017-05-02 07:38:23 +01:00
* Notice that terms are forcefully destroyed during backtracking.
*
2017-03-20 15:52:48 +00:00
*/
2017-05-02 07:38:23 +01:00
#include <vector>
2016-04-12 16:22:53 +01:00
2015-02-09 01:52:10 +00:00
#ifndef YAPT_HH
#define YAPT_HH 1
2016-09-21 20:41:23 +01:00
class YAPError;
2016-12-10 07:01:10 +00:00
2015-02-09 01:52:10 +00:00
/**
* @brief Generic Prolog Term
*/
2017-06-12 18:00:47 +01:00
class X_API YAPTerm {
2017-09-06 01:16:36 +01:00
friend class YAPPredicate;
friend class YAPPrologPredicate;
friend class YAPQuery;
friend class YAPModule;
friend class YAPModuleProp;
friend class YAPApplTerm;
friend class YAPListTerm;
2016-07-31 16:22:24 +01:00
2015-02-09 01:52:10 +00:00
protected:
2017-09-06 01:16:36 +01:00
yhandle_t t; /// handle to term, equivalent to term_t
2016-12-10 07:01:10 +00:00
2017-02-20 14:38:00 +00:00
public:
2017-09-06 01:16:36 +01:00
Term gt() {
CACHE_REGS
// fprintf(stderr,"?%d,%lx,%p\n",t,LOCAL_HandleBase[t], HR);
// Yap_DebugPlWriteln(LOCAL_HandleBase[t]);
return Yap_GetFromSlot(t);
};
void mk(Term t0) {
CACHE_REGS t = Yap_InitSlot(t0);
// fprintf(stderr,"+%d,%lx,%p,%p",t,t0,HR,ASP); Yap_DebugPlWriteln(t0);
};
void put(Term t0) {
Yap_PutInHandle(t, t0);
// fprintf(stderr,"+%d,%lx,%p,%p",t,t0,HR,ASP); Yap_DebugPlWriteln(t0);
};
YAPTerm(Term tn) { mk(tn); };
2016-12-10 07:01:10 +00:00
#ifdef SWIGPYTHON
2017-09-06 01:16:36 +01:00
// YAPTerm(struct _object *inp) {
// Term tinp = pythonToYAP(inp);
// t = Yap_InitSlot(tinp);
//}
2016-12-10 07:01:10 +00:00
#endif
2017-09-06 01:16:36 +01:00
/// private method to convert from Term (internal YAP representation) to
/// YAPTerm
// do nothing constructor
YAPTerm() { t = 0; };
// YAPTerm(yhandle_t i) { t = i; };
/// pointer to term
YAPTerm(void *ptr);
/// parse string s and construct a term.
YAPTerm(char *s) {
Term tp;
mk(YAP_ReadBuffer(s, &tp));
}
2017-02-20 14:38:00 +00:00
#if 1
2017-09-06 01:16:36 +01:00
/// Term destructor, tries to recover slot
virtual ~YAPTerm(){
// fprintf(stderr,"-%d,%lx,%p ",t,LOCAL_HandleBase[t] ,HR);
/* if (!t)
return;
Yap_DebugPlWriteln(LOCAL_HandleBase[t]);
LOCAL_HandleBase[t] = TermFreeTerm;
while (LOCAL_HandleBase[LOCAL_CurSlot - 1] == TermFreeTerm) {
LOCAL_CurSlot--;
}
*/
};
2017-02-20 14:38:00 +00:00
#endif
2017-09-06 01:16:36 +01:00
/// construct a term out of an integer (if you know object type use
/// YAPIntegerTerm)
/// YAPTerm(long int num) { mk(MkIntegerTerm(num)); }
/// construct a term out of an integer (if you know object type use
/// YAPIntegerTerm)
/// YAPTerm(double num) { mk(MkFloatTerm(num)); }
/// parse string s and construct a term.
/// YAPTerm(YAPFunctor f, YAPTerm ts[]);
/// extract the tag of a term, after dereferencing.
YAP_tag_t tag();
/// copy the term ( term copy )
Term deepCopy();
/// numbervars ( int start, bool process=false )
intptr_t numberVars(intptr_t start, bool skip_singletons = false);
inline Term term() {
return gt();
} /// from YAPTerm to Term (internal YAP representation)
2017-11-21 15:44:43 +00:00
YAPTerm arg(int i) {
BACKUP_MACHINE_REGS();
Term t0 = gt();
YAPTerm tf;
if (!IsApplTerm(t0) && !IsPairTerm(t))
return (Term)0;
tf = YAPTerm(ArgOfTerm(i, t0) );
RECOVER_MACHINE_REGS();
return tf;
};
inline void bind(Term b) { LOCAL_HandleBase[t] = b; }
2017-09-06 01:16:36 +01:00
inline void bind(YAPTerm *b) { LOCAL_HandleBase[t] = b->term(); }
/// from YAPTerm to Term (internal YAP representation)
/// fetch a sub-term
Term &operator[](arity_t n);
// const YAPTerm *vars();
/// this term is == to t1
virtual bool exactlyEqual(YAPTerm t1) {
bool out;
BACKUP_MACHINE_REGS();
out = Yap_eq(gt(), t1.term());
RECOVER_MACHINE_REGS();
return out;
};
/// t = t1
virtual bool unify(YAPTerm t1) {
intptr_t out;
BACKUP_MACHINE_REGS();
out = Yap_unify(gt(), t1.term());
RECOVER_MACHINE_REGS();
return out;
};
/// we can unify t and t1
virtual bool unifiable(YAPTerm t1) {
bool out;
BACKUP_MACHINE_REGS();
out = Yap_eq(gt(), t1.term());
RECOVER_MACHINE_REGS();
return out;
};
/// t =@= t1, the two terms are equal up to variable renamingvirtual bool
/// variant(
inline virtual YAP_Term variant(YAPTerm t1) {
intptr_t out;
BACKUP_MACHINE_REGS();
out = Yap_Variant(gt(), t1.term());
RECOVER_MACHINE_REGS();
return out;
};
virtual intptr_t hashTerm(size_t sz, size_t depth, bool variant) {
intptr_t out;
BACKUP_MACHINE_REGS();
out = Yap_TermHash(gt(), sz, depth, variant);
RECOVER_MACHINE_REGS();
return out;
};
/// term hash,
virtual bool isVar() { return IsVarTerm(gt()); } /// type check for unound
virtual bool isAtom() { return IsAtomTerm(gt()); } /// type check for atom
virtual bool isInteger() {
return IsIntegerTerm(gt());
} /// type check for integer
virtual bool isFloat() {
return IsFloatTerm(gt());
} /// type check for floating-point
virtual bool isString() {
return IsStringTerm(gt());
} /// type check for a string " ... "
virtual bool isCompound() {
return !(IsVarTerm(gt()) || IsNumTerm(gt()));
} /// is a primitive term
virtual bool isAppl() { return IsApplTerm(gt()); } /// is a structured term
virtual bool isPair() { return IsPairTerm(gt()); } /// is a pair term
virtual bool isGround() { return Yap_IsGroundTerm(gt()); } /// term is ground
virtual bool isList() { return Yap_IsListTerm(gt()); } /// term is a list
2017-12-05 15:14:57 +00:00
/// extract the argument i of the term, where i in 1...arityvoid *Yap_RepStreamFromId(int sno)
2017-09-06 01:16:36 +01:00
virtual Term getArg(arity_t i) {
BACKUP_MACHINE_REGS();
Term tf = 0;
Term t0 = gt();
if (IsApplTerm(t0)) {
if (i > ArityOfFunctor(FunctorOfTerm(t0)))
YAPError(DOMAIN_ERROR_OUT_OF_RANGE, t0, "t0.getArg()");
tf = (ArgOfTerm(i, t0));
} else if (IsPairTerm(t0)) {
if (i == 1)
tf = (HeadOfTerm(t0));
else if (i == 2)
tf = (TailOfTerm(t0));
else
YAPError(DOMAIN_ERROR_OUT_OF_RANGE, t0, "t0.getArg()");
} else {
YAPError(TYPE_ERROR_COMPOUND, t0, "t0.getArg()");
2015-02-09 01:52:10 +00:00
}
2017-09-06 01:16:36 +01:00
RECOVER_MACHINE_REGS();
return tf;
}
/// extract the arity of the term
/// variables have arity 0
virtual inline arity_t arity() {
Term t0 = gt();
if (IsApplTerm(t0)) {
Functor f = FunctorOfTerm(t0);
if (IsExtensionFunctor(f))
2017-07-25 01:10:44 +01:00
return 0;
2017-09-06 01:16:36 +01:00
return ArityOfFunctor(f);
} else if (IsPairTerm(t0)) {
return 2;
2017-02-20 14:38:00 +00:00
}
2017-09-06 01:16:36 +01:00
return 0;
}
/// return a string with a textual representation of the term
virtual const char *text() {
CACHE_REGS
encoding_t enc = LOCAL_encoding;
char *os;
BACKUP_MACHINE_REGS();
2017-12-01 10:42:10 +00:00
if (!(os = Yap_TermToBuffer(Yap_GetFromSlot(t), enc, Handle_vars_f))) {
2017-09-06 01:16:36 +01:00
RECOVER_MACHINE_REGS();
return 0;
}
RECOVER_MACHINE_REGS();
2017-10-02 08:58:51 +01:00
size_t length = strlen(os);
2017-09-06 01:16:36 +01:00
char *sm = (char *)malloc(length + 1);
strcpy(sm, os);
return sm;
};
/// return a handle to the term
inline yhandle_t handle() { return t; };
/// whether the term actually refers to a live object
inline bool initialized() { return t != 0; };
2015-02-09 01:52:10 +00:00
};
2017-06-15 22:40:55 +01:00
/**
* @brief YAPFunctor represents Prolog functors Name/Arity
*/
class X_API YAPFunctor : public YAPProp {
2017-09-06 01:16:36 +01:00
friend class YAPApplTerm;
friend class YAPTerm;
friend class YAPPredicate;
friend class YAPQuery;
Functor f;
/// Constructor: receives Prolog functor and casts it to YAPFunctor
///
/// Notice that this is designed for internal use only.
inline YAPFunctor(Functor ff) { f = ff; }
2017-06-15 22:40:55 +01:00
public:
2017-09-06 01:16:36 +01:00
/// Constructor: receives name as an atom, plus arity
///
/// This is the default method, and the most popular
YAPFunctor(YAPAtom at, uintptr_t arity) { f = Yap_MkFunctor(at.a, arity); }
/// Constructor: receives name as a string plus arity
///
/// Notice that this is designed for ISO-LATIN-1 right now
/// Note: Python confuses the 3 constructors,
/// use YAPFunctorFromString
inline YAPFunctor(const char *s, uintptr_t arity, bool isutf8 = true) {
f = Yap_MkFunctor(Yap_LookupAtom(s), arity);
}
/// Constructor: receives name as a wide string plus arity
///
/// Notice that this is designed for UNICODE right now
///
/// Note: Python confuses the 3 constructors,
/// use YAPFunctorFromWideString
inline YAPFunctor(const wchar_t *s, uintptr_t arity) {
CACHE_REGS f = Yap_MkFunctor(UTF32ToAtom(s PASS_REGS), arity);
}
/// Getter: extract name of functor as an atom
///
/// this is for external usage.
YAPAtom name(void) { return YAPAtom(NameOfFunctor(f)); }
/// Getter: extract arity of functor as an unsigned integer
///
/// this is for external usage.
uintptr_t arity(void) { return ArityOfFunctor(f); }
2017-06-15 22:40:55 +01:00
};
2015-02-09 01:52:10 +00:00
/**
* @brief Compound Term
*/
2017-06-12 18:00:47 +01:00
class X_API YAPApplTerm : public YAPTerm {
2017-09-06 01:16:36 +01:00
friend class YAPTerm;
2016-07-31 16:22:24 +01:00
2015-02-09 01:52:10 +00:00
public:
2017-09-06 01:16:36 +01:00
YAPApplTerm(Term t0) { mk(t0); }
YAPApplTerm(Functor f, Term ts[]) {
BACKUP_MACHINE_REGS();
Term t0 = Yap_MkApplTerm(f, f->ArityOfFE, ts);
mk(t0);
RECOVER_MACHINE_REGS();
};
YAPApplTerm(YAPFunctor f, YAPTerm ts[]);
YAPApplTerm(const std::string s, std::vector<YAPTerm> ts);
YAPApplTerm(YAPFunctor f);
inline Functor functor() { return FunctorOfTerm(gt()); }
inline YAPFunctor getFunctor() { return YAPFunctor(FunctorOfTerm(gt())); }
Term getArg(arity_t i) {
BACKUP_MACHINE_REGS();
Term t0 = gt();
Term tf;
tf = ArgOfTerm(i, t0);
RECOVER_MACHINE_REGS();
return tf;
};
2017-11-21 15:44:43 +00:00
virtual bool isVar() { return false; } /// type check for unbound
2017-09-06 01:16:36 +01:00
virtual bool isAtom() { return false; } /// type check for atom
virtual bool isInteger() { return false; } /// type check for integer
virtual bool isFloat() { return false; } /// type check for floating-point
virtual bool isString() { return false; } /// type check for a string " ... "
virtual bool isCompound() { return true; } /// is a primitive term
virtual bool isAppl() { return true; } /// is a structured term
virtual bool isPair() { return false; } /// is a pair term
virtual bool isGround() { return true; } /// term is ground
virtual bool isList() { return false; } /// [] is a list
2015-02-09 01:52:10 +00:00
};
/**
* @brief List Constructor Term
*/
2017-06-12 18:00:47 +01:00
class X_API YAPPairTerm : public YAPTerm {
2017-09-06 01:16:36 +01:00
friend class YAPTerm;
2016-07-31 16:22:24 +01:00
2015-02-09 01:52:10 +00:00
public:
2017-09-06 01:16:36 +01:00
YAPPairTerm(Term t0) {
t0 = Deref(t0);
if (IsPairTerm(t0) || t0 == TermNil)
mk(t0);
else
Yap_ThrowError(TYPE_ERROR_LIST, t0, "YAPPairTerms");
}
YAPPairTerm(YAPTerm hd, YAPTerm tl);
YAPPairTerm();
Term getHead() { return (HeadOfTerm(gt())); }
Term getTail() { return (TailOfTerm(gt())); }
2017-11-21 15:44:43 +00:00
YAPTerm car() { return YAPTerm(HeadOfTerm(gt())); }
bool nil() { return gt() == TermNil; }
YAPPairTerm cdr() { return YAPPairTerm(TailOfTerm(gt())); }
2017-09-06 01:16:36 +01:00
std::vector<Term> listToArray() {
Term *tailp;
Term t1 = gt();
Int l = Yap_SkipList(&t1, &tailp);
if (l < 0) {
throw YAPError(TYPE_ERROR_LIST, YAPTerm(t), "");
2017-05-02 07:38:23 +01:00
}
2017-09-06 01:16:36 +01:00
std::vector<Term> o = std::vector<Term>(l);
int i = 0;
Term t = gt();
while (t != TermNil) {
o[i++] = HeadOfTerm(t);
t = TailOfTerm(t);
2017-07-25 01:10:44 +01:00
}
2017-09-06 01:16:36 +01:00
return o;
}
2015-02-09 01:52:10 +00:00
};
2015-04-13 13:28:17 +01:00
/**
* @brief Number Term
*/
2017-06-12 18:00:47 +01:00
class X_API YAPNumberTerm : public YAPTerm {
2015-04-13 13:28:17 +01:00
public:
2017-09-06 01:16:36 +01:00
YAPNumberTerm(){};
bool isTagged() { return IsIntTerm(gt()); }
2015-04-13 13:28:17 +01:00
};
2015-02-09 01:52:10 +00:00
/**
* @brief Integer Term
*/
2017-06-12 18:00:47 +01:00
class X_API YAPIntegerTerm : public YAPNumberTerm {
2015-02-09 01:52:10 +00:00
public:
2017-09-06 01:16:36 +01:00
YAPIntegerTerm(intptr_t i);
intptr_t getInteger() { return IntegerOfTerm(gt()); };
2016-09-27 18:28:54 +01:00
};
/**
2017-02-20 14:38:00 +00:00
* @brief Floating Point Term
*/
2016-09-27 18:28:54 +01:00
2017-06-12 18:00:47 +01:00
class X_API YAPFloatTerm : public YAPNumberTerm {
2016-09-27 18:28:54 +01:00
public:
2017-09-06 01:16:36 +01:00
YAPFloatTerm(double dbl) { mk(MkFloatTerm(dbl)); };
2016-09-27 18:28:54 +01:00
2017-09-06 01:16:36 +01:00
double getFl() { return FloatOfTerm(gt()); };
2015-02-09 01:52:10 +00:00
};
2017-06-12 18:00:47 +01:00
class X_API YAPListTerm : public YAPTerm {
2015-02-09 01:52:10 +00:00
public:
2017-09-06 01:16:36 +01:00
/// Create a list term out of a standard term. Check if a valid operation.
///
/// @param[in] the term
YAPListTerm() { mk(TermNil); /* else type_error */ }
/// Create an empty list term.
///
/// @param[in] the term
YAPListTerm(Term t0) { mk(t0); /* else type_error */ }
/// Create a list term out of an array of terms.
///
/// @param[in] the array of terms
/// @param[in] the length of the array
YAPListTerm(YAPTerm ts[], size_t n);
// YAPListTerm( vector<YAPTerm> v );
/// Return the number of elements in a list term.
size_t length() {
Term *tailp;
Term t1 = gt();
return Yap_SkipList(&t1, &tailp);
}
/// Extract the nth element.
Term &operator[](size_t n);
/// Extract the first element of a list.
///
/// @param[in] the list
Term car();
/// Extract the tail elements of a list.
///
/// @param[in] the list
Term cdr() {
Term to = gt();
if (IsPairTerm(to))
return (TailOfTerm(to));
else if (to == TermNil)
return TermNil;
/* error */
throw YAPError(TYPE_ERROR_LIST, YAPTerm(to), "");
}
/// copy a list.
///
/// @param[in] the list
Term dup();
/// Check if the list is empty.
///
/// @param[in] the list
inline bool nil() {
return gt() == TermNil;
}
;
2015-02-09 01:52:10 +00:00
};
/**
* @brief String Term
*/
2017-06-12 18:00:47 +01:00
class X_API YAPStringTerm : public YAPTerm {
2015-02-09 01:52:10 +00:00
public:
2017-09-06 01:16:36 +01:00
/// your standard constructor
YAPStringTerm(char *s);
/// use this one to construct length limited strings
YAPStringTerm(char *s, size_t len);
/// construct using wide chars
YAPStringTerm(wchar_t *s);
/// construct using length-limited wide chars
YAPStringTerm(wchar_t *s, size_t len);
const char *getString() { return StringOfTerm(gt()); }
2016-07-31 16:22:24 +01:00
};
/**
* @brief Atom Term
* Term Representation of an Atom
*/
2017-06-12 18:00:47 +01:00
class X_API YAPAtomTerm : public YAPTerm {
2017-12-05 15:14:57 +00:00
friend class YAPModule;
2017-09-06 01:16:36 +01:00
// Constructor: receives a C-atom;
YAPAtomTerm(Term t) : YAPTerm(t) { IsAtomTerm(t); }
2016-07-31 16:22:24 +01:00
public:
2017-09-06 01:16:36 +01:00
YAPAtomTerm(Atom a) { mk(MkAtomTerm(a)); }
// Constructor: receives an atom;
YAPAtomTerm(YAPAtom a) : YAPTerm() { mk(MkAtomTerm(a.a)); }
2017-12-05 15:14:57 +00:00
// Constructor: receives a sequence of UTF-8 codes;
2017-09-06 01:16:36 +01:00
YAPAtomTerm(char s[]);
2017-12-05 15:14:57 +00:00
// Constructor: receives a sequence of up to n UTF-8 codes;
2017-09-06 01:16:36 +01:00
YAPAtomTerm(char *s, size_t len);
// Constructor: receives a sequence of wchar_ts, whatever they may be;
YAPAtomTerm(wchar_t *s);
2017-12-05 15:14:57 +00:00
// Constructor: receives a sequence of n wchar_ts, whatever they may be;
YAPAtomTerm(wchar_t *s, size_t len);
// Constructor: receives a std::string;
YAPAtomTerm(std::string s) { mk(MkAtomTerm(Yap_LookupAtom(s.c_str()))); };
bool isVar() { return false; } /// type check for unbound
2017-09-06 01:16:36 +01:00
bool isAtom() { return true; } /// type check for atom
bool isInteger() { return false; } /// type check for integer
bool isFloat() { return false; } /// type check for floating-point
bool isString() { return false; } /// type check for a string " ... "
bool isCompound() { return false; } /// is a primitive term
bool isAppl() { return false; } /// is a structured term
bool isPair() { return false; } /// is a pair term
virtual bool isGround() { return true; } /// term is ground
virtual bool isList() { return gt() == TermNil; } /// [] is a list
// Getter: outputs the atom;
YAPAtom getAtom() { return YAPAtom(AtomOfTerm(gt())); }
// Getter: outputs the name as a sequence of ISO-LATIN1 codes;
const char *text() { return (const char *)AtomOfTerm(gt())->StrOfAE; }
2015-02-09 01:52:10 +00:00
};
#endif /* YAPT_HH */
2017-03-20 15:52:48 +00:00
2017-06-12 18:00:47 +01:00
/**
* @brief Variable Term
*/
class X_API YAPVarTerm : public YAPTerm {
2017-09-06 01:16:36 +01:00
friend class YAPTerm;
2017-06-12 18:00:47 +01:00
public:
2017-09-06 01:16:36 +01:00
/// constructor
YAPVarTerm() { mk(MkVarTerm()); };
/// get the internal representation
CELL *getVar() { return VarOfTerm(gt()); }
/// is the variable bound to another one
YAPVarTerm(Term t) {
if (IsVarTerm(t)) {
mk(t);
2017-06-12 18:00:47 +01:00
}
2017-09-06 01:16:36 +01:00
}
bool unbound() { return IsUnboundVar(VarOfTerm(gt())); }
inline bool isVar() { return true; } /// type check for unbound
inline bool isAtom() { return false; } /// type check for atom
inline bool isInteger() { return false; } /// type check for integer
inline bool isFloat() { return false; } /// type check for floating-point
inline bool isString() { return false; } /// type check for a string " ... "
inline bool isCompound() { return false; } /// is a primitive term
inline bool isAppl() { return false; } /// is a structured term
inline bool isPair() { return false; } /// is a pair term
inline bool isGround() { return false; } /// term is ground
inline bool isList() { return false; } /// term is a list
2017-06-12 18:00:47 +01:00
};
2017-03-20 15:52:48 +00:00
/// @}