From 460dfafcc80bffe6aff6834d83712ebe257bfc15 Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Sun, 31 Jul 2016 10:22:24 -0500 Subject: [PATCH] improve C++ interface --- CXX/yapa.hh | 8 +- CXX/yapdb.hh | 64 +++++++---- CXX/yapi.cpp | 267 +++++++++++++++++++++++++++++++++---------- CXX/yapi.hh | 34 +++++- CXX/yapq.hh | 139 ++++++++++++++--------- CXX/yapt.hh | 311 +++++++++++++++++++++++++++++++-------------------- 6 files changed, 563 insertions(+), 260 deletions(-) diff --git a/CXX/yapa.hh b/CXX/yapa.hh index 409710039..e1b955817 100644 --- a/CXX/yapa.hh +++ b/CXX/yapa.hh @@ -47,12 +47,14 @@ enum PropTag { * */ class YAPAtom { + friend class YAPEngine; friend class YAPModuleProp; friend class YAPPredicate; friend class YAPFunctor; friend class YAPAtomTerm; friend class YAProp; friend class YAPModule; + friend class YAPQuery; Atom a; /// construct new YAPAtom from Atom YAPAtom( Atom at ) { a = at; } @@ -66,8 +68,10 @@ YAPAtom( const char * s, size_t len) { a = Yap_LookupAtomWithLength( s, len ); } /// construct new YAPAtom from max-length wide string YAPAtom( const wchar_t * s, size_t len) { a = Yap_LookupMaybeWideAtomWithLength( s, len ); } /// get name of atom - char *getName(void); - /// get prop of type + const char *getName(void); + /// get name of (other way) + inline const char *text(void) { return getName(); } ; + /// get prop of type Prop getProp( PropTag tag ) { return Yap_GetAProp( a , (PropFlags)tag ); } }; diff --git a/CXX/yapdb.hh b/CXX/yapdb.hh index 7c351bea0..83c775554 100644 --- a/CXX/yapdb.hh +++ b/CXX/yapdb.hh @@ -1,4 +1,8 @@ + +#ifndef _YAPDB_H +#define _YAPDB_H + #define YAP_CPP_DB_INTERFACE 1 //! @{ @@ -16,6 +20,7 @@ */ class YAPTerm; +class YAPAtomTerm; class YAPError; @@ -66,23 +71,32 @@ public: /// Constructor: receives Prolog functor and casts it to YAPFunctor /// /// Notice that this is designed for internal use only. - YAPFunctor( Functor ff) { f = ff; } + inline YAPFunctor( Functor ff) { f = ff; } public: - ~YAPFunctor( ) { }; + /// 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 - YAPFunctor( char * s, arity_t arity) { f = Yap_MkFunctor( Yap_LookupAtom( s ), 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 - YAPFunctor( wchar_t * s, arity_t arity) { f = Yap_MkFunctor( Yap_LookupWideAtom( s ), arity ) ; } - /// Constructor: receives name as an atom, plus arity /// - /// This is the default method, and the most popi;at - YAPFunctor( YAPAtom at, arity_t arity) { f = Yap_MkFunctor( at.a, arity ); } - - /// Getter: extract name of functor as an atom + /// Note: Python confuses the 3 constructors, + /// use YAPFunctorFromWideString + inline YAPFunctor( const wchar_t * s, uintptr_t arity) { + f = Yap_MkFunctor( + Yap_LookupWideAtom( s ), arity ) ; } + ~YAPFunctor( ) { }; + /// Getter: extract name of functor as an atom /// /// this is for external usage. YAPAtom name(void) { @@ -92,7 +106,7 @@ public: /// Getter: extract arity of functor as an unsigned integer /// /// this is for external usage. - arity_t arity(void) { + uintptr_t arity(void) { return ArityOfFunctor( f ); } @@ -117,17 +131,17 @@ protected: /// It also communicates the array of arguments t[] /// and the array of variables /// back to yapquery - YAPPredicate(const char *s, Term &out, Term &names ) { + YAPPredicate(const char *s0, Term &out, Term &names ) { CACHE_REGS BACKUP_MACHINE_REGS(); Term *outp; - - out = Yap_StringToTerm(s, strlen(s)+1, &LOCAL_encoding, 1200, &names ) ; - //extern char *s0; + + out = Yap_StringToTerm(s0, strlen(s0)+1, &LOCAL_encoding, 1200, &names ) ; + //extern char *s0; //fprintf(stderr,"ap=%p arity=%d text=%s", ap, ap->ArityOfPE, s); - // Yap_DebugPlWrite(out); - // delete [] ns; -if (out == 0L) + // Yap_DebugPlWrite(out); + // delete [] ns; + if (out == 0L) throw YAPError(SYNTAX_ERROR); ap = getPred( out, outp); RECOVER_MACHINE_REGS(); @@ -179,7 +193,7 @@ public: /// Mod:Name/Arity constructor for predicates. /// - inline YAPPredicate(YAPAtom at, arity_t arity, YAPModule mod) { + inline YAPPredicate(YAPAtom at, uintptr_t arity, YAPModule mod) { if (arity) { Functor f = Yap_MkFunctor(at.a, arity); ap = RepPredProp(PredPropByFunc(f,mod.t())); @@ -190,7 +204,7 @@ public: /// Atom/Arity constructor for predicates. /// - YAPPredicate(YAPAtom at, arity_t arity); + YAPPredicate(YAPAtom at, uintptr_t arity); /// module of a predicate @@ -215,7 +229,7 @@ public: /// arity of predicate /// /// we return a positive number. - arity_t getArity() { return ap->ArityOfPE; } + uintptr_t getArity() { return ap->ArityOfPE; } }; /** @@ -226,7 +240,7 @@ public: class YAPPrologPredicate: public YAPPredicate { public: YAPPrologPredicate(YAPAtom name, - arity_t arity, + uintptr_t arity, YAPModule module = YAPModule(), bool tabled = false, bool logical_updates = false, @@ -256,7 +270,7 @@ class YAPFLIP: public YAPPredicate { public: YAPFLIP(CPredicate call, YAPAtom name, - arity_t arity, + uintptr_t arity, YAPModule module = YAPModule(), CPredicate retry = 0, CPredicate cut = 0, @@ -277,7 +291,7 @@ public: }; YAPFLIP(const char *name, - arity_t arity, + uintptr_t arity, YAPModule module = YAPModule(), bool backtrackable = false ) : YAPPredicate( YAPAtom(name), arity, module) { @@ -299,3 +313,5 @@ public: } }; + +#endif diff --git a/CXX/yapi.cpp b/CXX/yapi.cpp index a5c6fe2cf..c91ab9b04 100644 --- a/CXX/yapi.cpp +++ b/CXX/yapi.cpp @@ -5,17 +5,21 @@ extern "C" { +#if __ANDROID__ +#include "android/log.h" +#endif + #include "YapInterface.h" #include "blobs.h" X_API char *Yap_TermToString(Term t, size_t *length, encoding_t encodingp, int flags); -X_API void YAP_UserCPredicate(const char *, YAP_UserCPred, YAP_Arity arity); -X_API void YAP_UserCPredicateWithArgs(const char *, YAP_UserCPred, YAP_Arity, +X_API void YAP_UserCPredicate(const char *, YAP_UserCPred, arity_t arity); +X_API void YAP_UserCPredicateWithArgs(const char *, YAP_UserCPred, arity_t, YAP_Term); X_API void YAP_UserBackCPredicate(const char *, YAP_UserCPred, YAP_UserCPred, - YAP_Arity, YAP_Arity); + arity_t, arity_t); } YAPAtomTerm::YAPAtomTerm(char *s) { // build string @@ -152,26 +156,61 @@ YAPStringTerm::YAPStringTerm(wchar_t *s, size_t len) YAPApplTerm::YAPApplTerm(YAPFunctor f, YAPTerm ts[]) : YAPTerm() { BACKUP_H(); - UInt arity = ArityOfFunctor(f.f); - mk(Yap_MkApplTerm(f.f, arity, (Term *)ts)); + arity_t arity = ArityOfFunctor(f.f); + Term *tt = new Term[arity]; + for (arity_t i = 0; i < arity; i++) + tt[i] = ts[i].term(); + mk(Yap_MkApplTerm(f.f, arity, tt)); + delete[] tt; RECOVER_H(); } YAPApplTerm::YAPApplTerm(YAPFunctor f) : YAPTerm() { BACKUP_H(); - UInt arity = ArityOfFunctor(f.f); + arity_t arity = ArityOfFunctor(f.f); mk(Yap_MkNewApplTerm(f.f, arity)); RECOVER_H(); } -YAPTerm YAPApplTerm::getArg(int arg) { - BACKUP_H(); - YAPTerm to = YAPTerm(ArgOfTerm(arg, gt())); - RECOVER_H(); - return to; +YAPFunctor YAPApplTerm::getFunctor() { return YAPFunctor(FunctorOfTerm(gt())); } + +static YAPTerm tmp; + +YAPTerm &YAPTerm::operator[](arity_t i) { + BACKUP_MACHINE_REGS(); + Term t0 = gt(); + Term tf = 0; + if (IsApplTerm(t0)) { + Functor f = FunctorOfTerm(t0); + if (IsExtensionFunctor(f)) + return *new YAPTerm(); + tf = ArgOfTerm(i + 1, t0); + } else if (IsPairTerm(t0)) { + if (i == 0) + tf = HeadOfTerm(t0); + else if (i == 1) + tf = TailOfTerm(t0); + } + RECOVER_MACHINE_REGS(); + return *new YAPTerm(tf); } -YAPFunctor YAPApplTerm::getFunctor() { return YAPFunctor(FunctorOfTerm(gt())); } +YAPTerm &YAPListTerm::operator[](arity_t i) { + BACKUP_MACHINE_REGS(); + Term t0 = gt(); + Term tf = 0; + while (IsPairTerm(t0)) { + if (i == 0) { + tf = HeadOfTerm(t0); + break; + } else { + t0 = TailOfTerm(t0); + i--; + } + } + RECOVER_MACHINE_REGS(); + return *new YAPTerm(tf); +} YAPPairTerm::YAPPairTerm(YAPTerm th, YAPTerm tl) : YAPTerm() { CACHE_REGS @@ -235,17 +274,36 @@ YAP_tag_t YAPTerm::tag() { } YAPTerm YAPTerm::deepCopy() { - Term tn; + yhandle_t tn; BACKUP_MACHINE_REGS(); tn = Yap_CopyTerm(gt()); RECOVER_MACHINE_REGS(); - return new YAPTerm(tn); + return *new YAPTerm(tn); +} + +YAPListTerm YAPListTerm::dup() { + yhandle_t tn; + BACKUP_MACHINE_REGS(); + + tn = Yap_CopyTerm(gt()); + + RECOVER_MACHINE_REGS(); + return *new YAPListTerm(tn); +} + +intptr_t YAPTerm::numberVars(intptr_t i0, bool skip_singletons) { + BACKUP_MACHINE_REGS(); + + intptr_t i = Yap_NumberVars(gt(), i0, skip_singletons); + + RECOVER_MACHINE_REGS(); + return i; } bool YAPTerm::exactlyEqual(YAPTerm t1) { - int out; + bool out; BACKUP_MACHINE_REGS(); out = Yap_eq(gt(), t1.term()); @@ -255,7 +313,7 @@ bool YAPTerm::exactlyEqual(YAPTerm t1) { } bool YAPTerm::unify(YAPTerm t1) { - int out; + intptr_t out; BACKUP_MACHINE_REGS(); out = Yap_unify(gt(), t1.term()); @@ -265,7 +323,7 @@ bool YAPTerm::unify(YAPTerm t1) { } bool YAPTerm::unifiable(YAPTerm t1) { - int out; + intptr_t out; BACKUP_MACHINE_REGS(); out = Yap_Unifiable(gt(), t1.term()); @@ -275,7 +333,7 @@ bool YAPTerm::unifiable(YAPTerm t1) { } bool YAPTerm::variant(YAPTerm t1) { - int out; + intptr_t out; BACKUP_MACHINE_REGS(); out = Yap_Variant(gt(), t1.term()); @@ -302,7 +360,8 @@ const char *YAPTerm::text() { char *os; BACKUP_MACHINE_REGS(); - if (!(os = Yap_TermToString(Yap_GetFromSlot(t), &length, enc, 0))) { + if (!(os = Yap_TermToString(Yap_GetFromSlot(t), &length, enc, + Handle_vars_f))) { RECOVER_MACHINE_REGS(); return nullptr; } @@ -340,19 +399,37 @@ YAPTerm::YAPTerm(intptr_t i) { YAPTerm YAPListTerm::car() { Term to = gt(); - { LOG("to=%lx", to); } if (IsPairTerm(to)) return YAPTerm(HeadOfTerm(to)); else throw YAPError(TYPE_ERROR_LIST); } +YAPListTerm::YAPListTerm(YAPTerm ts[], arity_t n) { + CACHE_REGS + BACKUP_H(); + if (n == 0) + t = TermNil; + while (HR + n * 2 > ASP - 1024) { + RECOVER_H(); + if (!Yap_dogc(0, NULL PASS_REGS)) { + t = TermNil; + } + BACKUP_H(); + } + t = AbsPair(HR); + for (arity_t i = 0; i < n; i++) { + HR[2 * i] = ts[i].gt(); + HR[2 * i + 1] = AbsPair(HR + (2 * i + 2)); + } +} + YAPVarTerm::YAPVarTerm() { CACHE_REGS mk(MkVarTerm()); } -char *YAPAtom::getName(void) { +const char *YAPAtom::getName(void) { if (IsWideAtom(a)) { // return an UTF-8 version size_t sz = 512; @@ -379,14 +456,16 @@ char *YAPAtom::getName(void) { void YAPQuery::initOpenQ() { CACHE_REGS - oq = LOCAL_execution; - LOCAL_execution = this; - q_open = 1; + // oq = LOCAL_execution; + // LOCAL_execution = this; + q_open = true; q_state = 0; q_flags = true; // PL_Q_PASS_EXCEPTION; q_p = P; q_cp = CP; + // make sure this is safe + q_handles = Yap_StartSlots(); } int YAPError::get() { return errNo; } @@ -403,6 +482,18 @@ void YAPQuery::initQuery(Term t) { } else { q_g = 0; } + q_pe = ap; + initOpenQ(); + RECOVER_MACHINE_REGS(); +} + +void YAPQuery::initQuery(YAPAtom at) { + CACHE_REGS + BACKUP_MACHINE_REGS(); + PredEntry *ap = RepPredProp(PredPropByAtom(at.a, Yap_CurrentModule())); + goal = YAPAtomTerm(at); + q_g = 0; + q_pe = ap; initOpenQ(); RECOVER_MACHINE_REGS(); } @@ -444,33 +535,55 @@ YAPQuery::YAPQuery(YAPPredicate p, YAPTerm ts[]) : YAPPredicate(p.ap) { YAPListTerm YAPQuery::namedVars() { CACHE_REGS - Term o = vnames.term(); - return o; // should be o + __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "vnames %s %d", + vnames.text(), LOCAL_CurSlot); + return vnames; // should be o +} + +YAPListTerm YAPQuery::namedVarsCopy() { + CACHE_REGS + __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "vnames %s %d", + vnames.text(), LOCAL_CurSlot); + return YAPListTerm(YAP_CopyTerm(vnames.term())); // should be o } bool YAPQuery::next() { CACHE_REGS - int result; + bool result; BACKUP_MACHINE_REGS(); - if (q_open != 1) + if (!q_open) return false; if (setjmp(q_env)) return false; - // don't forget, on success these guys must create slots - if (this->q_state == 0) { + // don't forget, on success these guys may create slots + __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "exec "); + + if (q_state == 0) { result = (bool)YAP_EnterGoal((YAP_PredEntryPtr)ap, q_g, &q_h); + } else { LOCAL_AllowRestart = q_open; result = (bool)YAP_RetryGoal(&q_h); } + { + if (result) + __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "vnames %d %s %d", + q_state, vnames.text(), LOCAL_CurSlot); + else + __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "fail"); + } q_state = 1; if (Yap_GetException()) { throw(YAPError(SYSTEM_ERROR_INTERNAL)); } + __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "out %d", result); + if (!result) { YAP_LeaveGoal(FALSE, &q_h); - q_open = 0; + q_open = false; + } else { + q_handles = Yap_StartSlots(); } RECOVER_MACHINE_REGS(); return result; @@ -480,11 +593,11 @@ void YAPQuery::cut() { CACHE_REGS BACKUP_MACHINE_REGS(); - if (q_open != 1 || q_state == 0) + if (!q_open || q_state == 0) return; YAP_LeaveGoal(FALSE, &q_h); q_open = 0; - LOCAL_execution = this; + // LOCAL_execution = this; RECOVER_MACHINE_REGS(); } @@ -492,13 +605,15 @@ bool YAPQuery::deterministic() { CACHE_REGS BACKUP_MACHINE_REGS(); - if (q_open != 1 || q_state == 0) + if (!q_open || q_state == 0) return false; choiceptr myB = (choiceptr)(LCL0 - q_h.b); return (B >= myB); RECOVER_MACHINE_REGS(); } +YAPTerm YAPQuery::getTerm(yhandle_t t) { return YAPTerm(t); } + void YAPQuery::close() { CACHE_REGS @@ -511,7 +626,7 @@ void YAPQuery::close() { } YAP_LeaveGoal(FALSE, &q_h); q_open = 0; - LOCAL_execution = this; + // LOCAL_execution = this; RECOVER_MACHINE_REGS(); } @@ -563,33 +678,55 @@ void Yap_displayWithJava(int c) { } } -extern "C" void Java_pt_up_fc_dcc_yap_JavaYap_load(JNIEnv *env0, jobject obj, - jobject mgr); - -extern "C" void Java_pt_up_fc_dcc_yap_JavaYap_load(JNIEnv *env0, jobject obj, - jobject asset_manager) { - AAssetManager *mgr = AAssetManager_fromJava(Yap_jenv, asset_manager); - if (mgr == NULL) { - LOG("we're doomed, mgr = 0; bip bip bip"); - } else { - Yap_assetManager = mgr; - } -} - #endif -YAPEngine::YAPEngine(char *savedState, size_t stackSize, size_t trailSize, - size_t maxStackSize, size_t maxTrailSize, char *libDir, - char *bootFile, char *goal, char *topLevel, bool script, - bool fastBoot, - YAPCallback *cb) - : _callback(0) { // a single engine can be active +void YAPEngine::doInit(YAP_file_type_t BootMode) { + if ((BootMode = YAP_Init(&init_args)) == YAP_FOUND_BOOT_ERROR) { + throw(YAPError(SYSTEM_ERROR_INTERNAL)); + } + /* Begin preprocessor code */ + /* live */ + __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "$init_system"); #if __ANDROID__ Yap_AndroidBufp = (char *)malloc(Yap_AndroidMax = 4096); Yap_AndroidBufp[0] = '\0'; Yap_AndroidSz = 0; #endif - memset((void *)&init_args, 0, sizeof(init_args)); + yerror = YAPError(); + + YAPQuery initq = YAPQuery(YAPAtom("$init_system")); + if (initq.next()) { + initq.cut(); + } else { + // should throw exception + } +} + +YAPEngine::YAPEngine(char *savedState, char *bootFile, size_t stackSize, + size_t trailSize, size_t maxStackSize, size_t maxTrailSize, + char *libDir, char *goal, char *topLevel, bool script, + bool fastBoot, + YAPCallback *cb) + : _callback(0) { // a single engine can be active + + YAP_file_type_t BootMode; + int Argc = 1; + char **Argv; + __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "YAP %s ", bootFile); + + // delYAPCallback()b + // if (cb) + // setYAPCallback(cb); + curren = this; + { + size_t l1 = 2 * sizeof(char *); + if (!(Argv = (char **)malloc(l1))) + return; + Argv[0] = (char *)malloc(4); + strcpy(Argv[0], "yap"); + Argv[1] = NULL; + } + BootMode = Yap_InitDefaults(&init_args, NULL, Argc, Argv); init_args.SavedState = savedState; init_args.StackSize = stackSize; init_args.TrailSize = trailSize; @@ -601,13 +738,20 @@ YAPEngine::YAPEngine(char *savedState, size_t stackSize, size_t trailSize, init_args.YapPrologTopLevelGoal = topLevel; init_args.HaltAfterConsult = script; init_args.FastBoot = fastBoot; - yerror = YAPError(); - delYAPCallback(); - if (cb) - setYAPCallback(cb); + doInit(BootMode); +} + +YAPEngine::YAPEngine(int argc, char *argv[], + YAPCallback *cb) + : _callback(0) { // a single engine can be active + + YAP_file_type_t BootMode; + BootMode = YAP_parse_yap_arguments(argc, argv, &init_args); + // delYAPCallback()b + // if (cb) + // setYAPCallback(cb); curren = this; - if (YAP_Init(&init_args) == YAP_BOOT_ERROR) - throw(YAPError(SYSTEM_ERROR_INTERNAL)); + doInit(BootMode); } YAPPredicate::YAPPredicate(YAPAtom at) { @@ -642,6 +786,7 @@ PredEntry *YAPPredicate::getPred(Term &t, Term *&outp) { ts[0] = t; ts[1] = m; t = Yap_MkApplTerm(FunctorCsult, 2, ts); + outp = RepAppl(t) + 1; } Functor f = FunctorOfTerm(t); if (IsExtensionFunctor(f)) { diff --git a/CXX/yapi.hh b/CXX/yapi.hh index cacdb736b..ab27e9197 100644 --- a/CXX/yapi.hh +++ b/CXX/yapi.hh @@ -1,10 +1,11 @@ + #define YAP_CPP_INTERFACE 1 #include -//! @{ +//! @{ /** * * @defgroup yap-cplus-interface An object oriented interface for YAP. @@ -65,6 +66,35 @@ extern "C" { // taken from yap_structs.h #include "iopreds.h" +#ifdef SWIGPYTHON +extern PyObject *term_to_python(yhandle_t t, bool eval); +extern PyObject *deref_term_to_python(yhandle_t t); +X_API bool init_python(void); + +extern PyObject *py_Main; + +extern inline PyObject *AtomToPy( const char *s) +{ + if (strcmp(s, "true") == 0) + return Py_True; + if (strcmp(s, "false") == 0) + return Py_False; + if (strcmp(s, "none") == 0) + return Py_None; + if (strcmp(s, "[]") == 0) + return PyList_New(0); + else if (strcmp(s, "{}") == 0) + return PyDict_New(); + /* return __main__,s */ + else if (PyObject_HasAttrString(py_Main, s)) { + return PyObject_GetAttrString(py_Main, s); + } + // no way to translate + return NULL; +} + +#endif + X_API void YAP_UserCPredicate(const char *, YAP_UserCPred, YAP_Arity arity); /* void UserCPredicateWithArgs(const char *name, int *fn(), unsigned int arity) */ @@ -76,6 +106,8 @@ X_API void YAP_UserCPredicateWithArgs(const char *, YAP_UserCPred, YAP_Arity, YA X_API Term Yap_StringToTerm(const char *s, size_t len, encoding_t *encp, int prio, Term *bindings_p); + + } class YAPEngine; diff --git a/CXX/yapq.hh b/CXX/yapq.hh index 21edd1915..e8582ae38 100644 --- a/CXX/yapq.hh +++ b/CXX/yapq.hh @@ -1,6 +1,8 @@ #ifndef YAPQ_HH #define YAPQ_HH 1 +class YAPPredicate; + /** Queries and engines */ @@ -11,24 +13,37 @@ * interface to a YAP Query; * uses an SWI-like status info internally. */ -class YAPQuery: public YAPPredicate, public open_query_struct { +class YAPQuery : public YAPPredicate { + bool q_open; + int q_state; + yhandle_t q_g, q_handles; + struct pred_entry *q_pe; + struct yami *q_p, *q_cp; + jmp_buf q_env; + int q_flags; + YAP_dogoalinfo q_h; + YAPQuery *oq; YAPListTerm vnames; YAPTerm goal; Term names; Term t; - void initOpenQ(); - void initQuery( Term t ); - void initQuery( YAPTerm ts[], arity_t arity ); + void initOpenQ(); + void initQuery(Term t); + void initQuery(YAPAtom at); + void initQuery(YAPTerm ts[], arity_t arity); + public: /// main constructor, uses a predicate and an array of terms /// - /// It is given a YAPPredicate _p_ , and an array of terms that must have at least + /// It is given a YAPPredicate _p_ , and an array of terms that must have at + /// least /// the same arity as the functor. YAPQuery(YAPPredicate p, YAPTerm t[]); /// full constructor, /// - /// It is given a functor, module, and an array of terms that must have at least + /// It is given a functor, module, and an array of terms that must have at + /// least /// the same arity as the functor. YAPQuery(YAPFunctor f, YAPTerm mod, YAPTerm t[]); /// functor/term constructor, @@ -38,19 +53,30 @@ public: YAPQuery(YAPFunctor f, YAPTerm t[]); /// string constructor without varnames /// - /// It is given a string, calls the parser and obtains a Prolog term that should be a callable + /// It is given a string, calls the parser and obtains a Prolog term that + /// should be a callable /// goal. - inline YAPQuery(const char *s): YAPPredicate(s, t, names) - { - vnames = YAPListTerm( names ); + inline YAPQuery(const char *s) : YAPPredicate(s, t, names) { + __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "got game %d", + LOCAL_CurSlot); - initQuery( t ); + vnames = YAPListTerm(names); + __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "%s", vnames.text()); + initQuery(t); + }; + /// string constructor with just an atom + /// + /// It is given an atom, and a Prolog term that should be a callable + /// goal, say `main`, `init`, `live`. + inline YAPQuery(YAPAtom goal) : YAPPredicate(goal) { + vnames = YAPListTerm(TermNil); + initQuery(goal); }; /// set flags for query execution, currently only for exception handling - void setFlag(int flag) {q_flags |= flag; } + void setFlag(int flag) { q_flags |= flag; } /// reset flags for query execution, currently only for exception handling - void resetFlag(int flag) {q_flags &= ~flag; } + void resetFlag(int flag) { q_flags &= ~flag; } /// first query /// /// actually implemented by calling the next(); @@ -63,17 +89,21 @@ public: bool deterministic(); /// represent the top-goal const char *text(); - /// remove alternatives in the current search space, and finish the current query + /// remove alternatives in the current search space, and finish the current + /// query void cut(); /// finish the current query: undo all bindings. void close(); /// query variables. YAPListTerm namedVars(); - ///simple YAP Query; + /// query variables, but copied out + YAPListTerm namedVarsCopy(); + /// convert a ref to a binding. + YAPTerm getTerm(yhandle_t t); + /// simple YAP Query; /// just calls YAP and reports success or failure, Useful when we just /// want things done, eg YAPCommand("load_files(library(lists), )") - inline bool command() - { + inline bool command() { bool rc = next(); close(); return rc; @@ -82,13 +112,14 @@ public: // Java support -/// This class implements a callback Prolog-side. It will be inherited by the Java or Python +/// This class implements a callback Prolog-side. It will be inherited by the +/// Java or Python /// class that actually implements the callback. class YAPCallback { public: - virtual ~YAPCallback() { } - virtual void run() { LOG("callback"); } - virtual void run(char *s) { } + virtual ~YAPCallback() {} + virtual void run() { LOG("callback"); } + virtual void run(char *s) {} }; /** @@ -102,48 +133,56 @@ private: YAPCallback *_callback; YAP_init_args init_args; YAPError yerror; + void doInit(YAP_file_type_t BootMode); + public: - YAPEngine(char *savedState = (char *)NULL, - size_t stackSize = 0, - size_t trailSize = 0, - size_t maxStackSize = 0, - size_t maxTrailSize = 0, - char *libDir = (char *)NULL, - char *bootFile = (char *)NULL, - char *goal = (char *)NULL, - char *topLevel = (char *)NULL, - bool script = FALSE, - bool fastBoot = FALSE, - YAPCallback *callback=(YAPCallback *)NULL); /// construct a new engine, including aaccess to callbacks - /// kill engine + /// construct a new engine; may use a variable number of arguments + YAPEngine( + char *savedState = (char *)NULL, char *bootFile = (char *)NULL, + size_t stackSize = 0, size_t trailSize = 0, size_t maxStackSize = 0, + size_t maxTrailSize = 0, char *libDir = (char *)NULL, + char *goal = (char *)NULL, char *topLevel = (char *)NULL, + bool script = FALSE, bool fastBoot = FALSE, + YAPCallback *callback = (YAPCallback *) + NULL); /// construct a new engine, including aaccess to callbacks + /// construct a new engine using argc/argv list of arguments + YAPEngine(int argc, char *argv[], + YAPCallback *callback = (YAPCallback *)NULL); + /// kill engine ~YAPEngine() { delYAPCallback(); } /// remove current callback void delYAPCallback() { _callback = 0; } /// set a new callback - void setYAPCallback(YAPCallback *cb) { delYAPCallback(); _callback = cb; } + void setYAPCallback(YAPCallback *cb) { + delYAPCallback(); + _callback = cb; + } /// execute the callback. ////void run() { if (_callback) _callback->run(); } /// execute the callback with a text argument. - void run( char *s) { if (_callback) _callback->run(s); } + void run(char *s) { + if (_callback) + _callback->run(s); + } /// execute the callback with a text argument. - YAPError hasError( ) { return yerror.get(); } + YAPError hasError() { return yerror.get(); } /// build a query on the engine - YAPQuery *query( const char *s ) { - return new YAPQuery( s ); - }; + YAPQuery *query(const char *s) { return new YAPQuery(s); }; /// current module for the engine - YAPModule currentModule( ) { return YAPModule( ) ; } + YAPModule currentModule() { return YAPModule(); } + /// given a handle, fetch a term from the engine + inline YAPTerm getTerm(yhandle_t h) { return YAPTerm(h); } /// current directory for the engine - const char *currentDir( ) { - char dir[1024]; - std::string s = Yap_getcwd(dir, 1024-1); - return s.c_str(); - } + const char *currentDir() { + char dir[1024]; + std::string s = Yap_getcwd(dir, 1024 - 1); + return s.c_str(); + }; /// report YAP version as a string - const char *version( ) { - std::string s = Yap_version(); - return s.c_str(); - } + const char *version() { + std::string s = Yap_version(); + return s.c_str(); + }; }; #endif /* YAPQ_HH */ diff --git a/CXX/yapt.hh b/CXX/yapt.hh index 46368d0a0..680c0a27a 100644 --- a/CXX/yapt.hh +++ b/CXX/yapt.hh @@ -2,7 +2,7 @@ #ifndef YAPT_HH #define YAPT_HH 1 -extern "C" Term YAP_ReadBuffer(const char *s, Term *tp); +extern "C" Term YAP_ReadBuffer(const char *s, Term *tp); /** * @brief Generic Prolog Term @@ -14,188 +14,209 @@ class YAPTerm { friend class YAPModule; friend class YAPModuleProp; friend class YAPApplTerm; + friend class YAPListTerm; + protected: - yhandle_t t; /// handle to term, equivalent to term_t + yhandle_t t; /// handle to term, equivalent to term_t void mk(Term t0); /// internal method to convert from term to handle - Term gt(); /// get handle and obtain term + Term gt(); /// get handle and obtain term public: - virtual ~YAPTerm() {}; - YAPTerm(Term tn) { mk( tn ); } /// private method to convert from Term (internal YAP representation) to YAPTerm + virtual ~YAPTerm(){}; + YAPTerm(Term tn) { + mk(tn); + } /// private method to convert from Term (internal YAP representation) to + /// YAPTerm // do nothing constructor - YAPTerm() { mk(TermNil); } - /// integer to term + YAPTerm() { t = 0; } YAPTerm(intptr_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) ); } + YAPTerm(char *s) { + Term tp; + mk(YAP_ReadBuffer(s, &tp)); + } /// extract the tag of a term, after dereferencing. - YAP_tag_t tag(); + YAP_tag_t tag(); /// copy the term ( term copy ) - YAPTerm deepCopy(); - inline Term term() { return gt(); } /// from YAPTerm to Term (internal YAP representation) - //const YAPTerm *vars(); + YAPTerm 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) + /// fetch a sub-term + YAPTerm &operator[](size_t n); + // const YAPTerm *vars(); /// this term is == to t1 - bool exactlyEqual(YAPTerm t1); - bool unify(YAPTerm t1); /// t = t1 - bool unifiable(YAPTerm t1); /// we can unify t and t1 - bool variant(YAPTerm t1); /// t =@= t1, the two terms are equal up to variable renaming - intptr_t hashTerm(size_t sz, size_t depth, bool variant); /// term hash, - virtual bool isVar() { return IsVarTerm( gt() ); } /// type check for unbound - 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 + virtual bool exactlyEqual(YAPTerm t1); + virtual bool unify(YAPTerm t1); /// t = t1 + virtual bool unifiable(YAPTerm t1); /// we can unify t and t1 + virtual bool variant( + YAPTerm t1); /// t =@= t1, the two terms are equal up to variable renaming + virtual intptr_t hashTerm(size_t sz, size_t depth, + bool variant); /// 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 /// extract the argument i of the term, where i in 1...arity - inline YAPTerm getArg(int i) { + inline YAPTerm getArg(arity_t i) { BACKUP_MACHINE_REGS(); Term t0 = gt(); YAPTerm tf; if (IsApplTerm(t0)) tf = YAPTerm(ArgOfTerm(i, t0)); else if (IsPairTerm(t0)) { - if (i==1) + if (i == 1) tf = YAPTerm(HeadOfTerm(t0)); - else if (i==2) - tf = YAPTerm(TailOfTerm(t0)); + else if (i == 2) + tf = YAPTerm(TailOfTerm(t0)); } else { tf = YAPTerm((Term)0); } RECOVER_MACHINE_REGS(); - REGS_LOG( "after getArg H= %p, i=%d", HR, tf.gt()) ; 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)) + return 0; + return ArityOfFunctor(f); + } else if (IsPairTerm(t0)) { + return 2; + } + return 0; + } + /// return a string with a textual representation of the term virtual const char *text(); + + /// return a handle to the term + inline yhandle_t handle() { return t; }; }; /** * @brief Variable Term */ -class YAPVarTerm: public YAPTerm { - YAPVarTerm(Term t) { if (IsVarTerm(t)) mk( t ); } +class YAPVarTerm : public YAPTerm { + YAPVarTerm(Term t) { + if (IsVarTerm(t)) + mk(t); + } + public: /// constructor YAPVarTerm(); /// get the internal representation - CELL *getVar() { return VarOfTerm( gt() ); } + CELL *getVar() { return VarOfTerm(gt()); } /// is the variable bound to another one - bool unbound() { return IsUnboundVar(VarOfTerm( gt() )); } - virtual bool isVar() { return true; } /// type check for unbound - virtual bool isAtom() { return false; } /// type check for atom + bool unbound() { return IsUnboundVar(VarOfTerm(gt())); } + virtual bool isVar() { return true; } /// type check for unbound + 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 isFloat() { return false; } /// type check for floating-point + virtual bool isString() { return false; } /// type check for a string " ... " virtual bool isCompound() { return false; } /// is a primitive term - virtual bool isAppl() { return false; } /// is a structured term - virtual bool isPair() { return false; } /// is a pair term - virtual bool isGround() { return false; } /// term is ground - virtual bool isList() { return false; } /// term is a list -}; - -/** - * @brief Atom Term - * Term Representation of an Atom - */ -class YAPAtomTerm: public YAPTerm { - friend class YAPModule; - // Constructor: receives a C-atom; - YAPAtomTerm(Atom a) { mk( MkAtomTerm(a) ); } - YAPAtomTerm(Term t): YAPTerm(t) { IsAtomTerm(t); } - // Getter for Prolog atom - Term getTerm() { return t; } -public: - // Constructor: receives an atom; - YAPAtomTerm(YAPAtom a): YAPTerm() { mk( MkAtomTerm(a.a) ); } - // Constructor: receives a sequence of ISO-LATIN1 codes; - YAPAtomTerm(char *s) ; - // Constructor: receives a sequence of up to n ISO-LATIN1 codes; - YAPAtomTerm(char *s, size_t len); - // Constructor: receives a sequence of wchar_ts, whatever they may be; - YAPAtomTerm(wchar_t *s) ; - // Constructor: receives a sequence of n wchar_ts, whatever they may be; - YAPAtomTerm(wchar_t *s, size_t len); - virtual bool isVar() { return false; } /// type check for unbound - virtual bool isAtom() { return true; } /// 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 false; } /// is a primitive term - virtual bool isAppl() { return false; } /// 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 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; } + virtual bool isAppl() { return false; } /// is a structured term + virtual bool isPair() { return false; } /// is a pair term + virtual bool isGround() { return false; } /// term is ground + virtual bool isList() { return false; } /// term is a list }; /** * @brief Compound Term */ -class YAPApplTerm: public YAPTerm { +class YAPApplTerm : public YAPTerm { friend class YAPTerm; YAPApplTerm(Term t0) { mk(t0); } + public: - ~YAPApplTerm() { } + ~YAPApplTerm() {} YAPApplTerm(YAPFunctor f, YAPTerm ts[]); YAPApplTerm(YAPFunctor f); YAPFunctor getFunctor(); - YAPTerm getArg(int i); - virtual bool isVar() { return false; } /// type check for unbound - virtual bool isAtom() { return false; } /// type check for atom + inline YAPTerm getArg(arity_t i) { + BACKUP_MACHINE_REGS(); + Term t0 = gt(); + YAPTerm tf; + tf = YAPTerm(ArgOfTerm(i, t0)); + RECOVER_MACHINE_REGS(); + return tf; + }; + virtual bool isVar() { return false; } /// type check for unbound + 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 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 + 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 }; /** * @brief List Constructor Term */ -class YAPPairTerm: public YAPTerm { +class YAPPairTerm : public YAPTerm { friend class YAPTerm; - YAPPairTerm(Term t0) { if (IsPairTerm(t0)) mk( t0 ); else mk(0); } + YAPPairTerm(Term t0) { + if (IsPairTerm(t0)) + mk(t0); + else + mk(0); + } + public: YAPPairTerm(YAPTerm hd, YAPTerm tl); YAPPairTerm(); - YAPTerm getHead() { return YAPTerm(HeadOfTerm( gt() )); } - YAPTerm getTail() { return YAPTerm(TailOfTerm( gt() )); } + YAPTerm getHead() { return YAPTerm(HeadOfTerm(gt())); } + YAPTerm getTail() { return YAPTerm(TailOfTerm(gt())); } }; /** * @brief Number Term */ -class YAPNumberTerm: public YAPTerm { +class YAPNumberTerm : public YAPTerm { public: - YAPNumberTerm() {}; - bool isTagged() { return IsIntTerm( gt() ); } + YAPNumberTerm(){}; + bool isTagged() { return IsIntTerm(gt()); } }; /** * @brief Integer Term */ -class YAPIntegerTerm: public YAPNumberTerm { +class YAPIntegerTerm : public YAPNumberTerm { public: YAPIntegerTerm(intptr_t i); - intptr_t getInteger() { return IntegerOfTerm( gt() ); } + intptr_t getInteger() { return IntegerOfTerm(gt()); } }; -class YAPListTerm: public YAPTerm { +class YAPListTerm : public YAPTerm { public: /// Create a list term out of a standard term. Check if a valid operation. /// @@ -205,15 +226,20 @@ public: /// /// @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); - */ + /// 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 v ); /// Return the number of elements in a list term. - size_t length() { Term *tailp; Term t1 = gt(); return Yap_SkipList(&t1, &tailp); } + size_t length() { + Term *tailp; + Term t1 = gt(); + return Yap_SkipList(&t1, &tailp); + } + /// Extract the nth element. + YAPTerm &operator[](size_t n); /// Extract the first element of a list. /// /// @param[in] the list @@ -221,42 +247,83 @@ public: /// Extract the tail elements of a list. /// /// @param[in] the list - YAPListTerm cdr() - { + YAPListTerm cdr() { Term to = gt(); - if (IsPairTerm( to )) - return YAPListTerm(TailOfTerm( to )); - else if ( to == TermNil) - return YAPListTerm( ); + if (IsPairTerm(to)) + return YAPListTerm(TailOfTerm(to)); + else if (to == TermNil) + return YAPListTerm(); /* error */ throw YAPError(TYPE_ERROR_LIST); } + /// copy a list. + /// + /// @param[in] the list + YAPListTerm dup(); /// Check if the list is empty. /// /// @param[in] the list inline bool nil() { - { LOG( "II %x %x", gt(), TermNil) ; } return gt() == TermNil; } -; + ; }; /** * @brief String Term */ -class YAPStringTerm: public YAPTerm { +class YAPStringTerm : public YAPTerm { public: /// your standard constructor - YAPStringTerm(char *s) ; + 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) ; + YAPStringTerm(wchar_t *s); /// construct using length-limited wide chars YAPStringTerm(wchar_t *s, size_t len); - const char *getString() { return StringOfTerm( gt() ); } + const char *getString() { return StringOfTerm(gt()); } +}; + +/** + * @brief Atom Term + * Term Representation of an Atom + */ +class YAPAtomTerm : public YAPTerm { + friend class YAPModule; + // Constructor: receives a C-atom; + YAPAtomTerm(Atom a) { mk(MkAtomTerm(a)); } + YAPAtomTerm(Term t) : YAPTerm(t) { IsAtomTerm(t); } + // Getter for Prolog atom + Term getTerm() { return t; } + +public: + // Constructor: receives an atom; + YAPAtomTerm(YAPAtom a) : YAPTerm() { mk(MkAtomTerm(a.a)); } + // Constructor: receives a sequence of ISO-LATIN1 codes; + YAPAtomTerm(char *s); + // Constructor: receives a sequence of up to n ISO-LATIN1 codes; + YAPAtomTerm(char *s, size_t len); + // Constructor: receives a sequence of wchar_ts, whatever they may be; + YAPAtomTerm(wchar_t *s); + // Constructor: receives a sequence of n wchar_ts, whatever they may be; + YAPAtomTerm(wchar_t *s, size_t len); + virtual bool isVar() { return false; } /// type check for unbound + virtual bool isAtom() { return true; } /// 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 false; } /// is a primitive term + virtual bool isAppl() { return false; } /// 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 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; } }; #endif /* YAPT_HH */