diff --git a/CXX/CMakeLists.txt b/CXX/CMakeLists.txt index 4d2c8a390..80259bad8 100644 --- a/CXX/CMakeLists.txt +++ b/CXX/CMakeLists.txt @@ -28,9 +28,9 @@ else() MY_target_link_libraries(YAP++ ${CMAKE_DL_LIBS} libYap) MY_install(TARGETS YAP++ - LIBRARY DESTINATION ${dlls} + LIBRARY DESTINATION ${libdir} RUNTIME DESTINATION ${dlls} - ARCHIVE DESTINATION ${dlls} + ARCHIVE DESTINATION ${libdir} ) endif() diff --git a/CXX/yapdb.hh b/CXX/yapdb.hh index ac8d3a3e2..cd617862b 100644 --- a/CXX/yapdb.hh +++ b/CXX/yapdb.hh @@ -22,11 +22,11 @@ * programs: * * + YAPFunctor represents a name/arity combination. - * + * * + YAPModule wraps the YAP module implementation. * - * + YAPPredicate and subclasses store the actual program, Preliminary - * support covers Prolog and C-defined predicates. + * + YAPPredicate and subclasses store the actual program, Preliminary + * support covers Prolog and C-defined predicates. */ class YAPTerm; @@ -134,7 +134,7 @@ protected: PredEntry *ap; /// auxiliary routine to find a predicate in the current module. - PredEntry *getPred(Term &t, Term *&outp); + PredEntry *getPred(YAPTerm &t, Term *&outp); PredEntry *asPred() { return ap; }; @@ -143,23 +143,20 @@ protected: /// It also communicates the array of arguments t[] /// and the array of variables /// back to yapquery - YAPPredicate(const char *s0, Term &out, Term &names) { + YAPPredicate(const char *s0, Term &tout, Term &tnames) { CACHE_REGS - BACKUP_MACHINE_REGS(); Term *modp = NULL; - names = MkVarTerm (); const unsigned char *us = (const unsigned char *)s0; - out = - Yap_BufferToTermWithPrioBindings(us, strlen(s0), TermNil, 1200, names); - // extern char *s0; + tnames = MkVarTerm(); + tout = + Yap_BufferToTermWithPrioBindings(us, strlen(s0), TermNil, 1200, tnames); // fprintf(stderr,"ap=%p arity=%d text=%s", ap, ap->ArityOfPE, s); // Yap_DebugPlWrite(out); - // delete [] ns; - if (out == 0L) - ap = nullptr; - else - ap = getPred(out, modp); - RECOVER_MACHINE_REGS(); + if (tout == 0L) { + Yap_ThrowError(TYPE_ERROR_PREDICATE_INDICATOR, MkStringTerm(s0), "YAPPredicate"); + } + YAPTerm tt = YAPTerm(tout); + ap = getPred(tt, modp); } /// Term constructor for predicates @@ -167,7 +164,8 @@ protected: /// It is just a call to getPred inline YAPPredicate(Term t) { CELL *v = NULL; - ap = getPred(t, v); + YAPTerm tt = YAPTerm(t); + ap = getPred(tt, v); } /// Term constructor for predicates @@ -175,8 +173,7 @@ protected: /// It is just a call to getPred inline YAPPredicate(YAPTerm t) { Term *v = nullptr; - Term tt = t.term(); - ap = getPred(tt, v); + ap = getPred(t, v); } /// Cast constructor for predicates, @@ -197,13 +194,13 @@ public: /// Functor constructor for predicates, is given a specific module. /// inline YAPPredicate(YAPFunctor f, YAPTerm mod) { - ap = RepPredProp(PredPropByFunc(f.f, mod.t)); + ap = RepPredProp(PredPropByFunc(f.f, mod.term())); } /// Name/arity constructor for predicates. /// inline YAPPredicate(YAPAtom at, YAPTerm mod) { - ap = RepPredProp(PredPropByAtom(at.a, mod.t)); + ap = RepPredProp(PredPropByAtom(at.a, mod.term())); } /// Name/0 constructor for predicates. @@ -215,9 +212,9 @@ public: inline YAPPredicate(YAPAtom at, uintptr_t arity, YAPModule mod) { if (arity) { Functor f = Yap_MkFunctor(at.a, arity); - ap = RepPredProp(PredPropByFunc(f, mod.t())); + ap = RepPredProp(PredPropByFunc(f, mod.term())); } else { - ap = RepPredProp(PredPropByAtom(at.a, mod.t())); + ap = RepPredProp(PredPropByAtom(at.a, mod.term())); } } @@ -236,13 +233,13 @@ public: /// inline YAPPredicate(const char *at, uintptr_t arity, YAPTerm mod) { ap = RepPredProp( - PredPropByFunc(Yap_MkFunctor(Yap_LookupAtom(at), arity), mod.t)); + PredPropByFunc(Yap_MkFunctor(Yap_LookupAtom(at), arity), mod.term())); }; /// char */module constructor for predicates. /// inline YAPPredicate(const char *at, YAPTerm mod) { - ap = RepPredProp(PredPropByAtom(Yap_LookupAtom(at), mod.t)); + ap = RepPredProp(PredPropByAtom(Yap_LookupAtom(at), mod.term())); } /// module of a predicate @@ -271,7 +268,7 @@ public: YAPFunctor functor() { if (ap->ArityOfPE) return YAPFunctor(ap->FunctorOfPred); - return NULL; +Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, MkIntTerm(0), "YAPFunctor::functor"); } /// arity of predicate diff --git a/CXX/yapi.cpp b/CXX/yapi.cpp index 92ebe6fb6..0c7fbe08c 100644 --- a/CXX/yapi.cpp +++ b/CXX/yapi.cpp @@ -1,4 +1,6 @@ + + #define YAP_CPP_INTERFACE 1 #include "yapi.hh" @@ -11,14 +13,21 @@ extern "C" { #include "YapInterface.h" #include "blobs.h" -X_API char *Yap_TermToString(Term t, size_t *length, encoding_t encodingp, +X_API extern char *Yap_TermToString(Term t, size_t *length, encoding_t encodingp, int flags); -X_API void YAP_UserCPredicate(const char *, YAP_UserCPred, arity_t arity); -X_API void YAP_UserCPredicateWithArgs(const char *, YAP_UserCPred, arity_t, +X_API extern void YAP_UserCPredicate(const char *, YAP_UserCPred, arity_t arity); +X_API extern void YAP_UserCPredicateWithArgs(const char *, YAP_UserCPred, arity_t, YAP_Term); -X_API void YAP_UserBackCPredicate(const char *, YAP_UserCPred, YAP_UserCPred, +X_API extern void YAP_UserBackCPredicate(const char *, YAP_UserCPred, YAP_UserCPred, arity_t, arity_t); +#if YAP_PYTHON + extern bool python_in_python; + X_API extern bool init_python(void); + extern X_API bool Py_IsInitialized(); + +#endif + } YAPAtomTerm::YAPAtomTerm(char *s) @@ -239,7 +248,7 @@ Term &YAPListTerm::operator[](arity_t i) return RepPair(tf)[i]; } -YAPPairTerm::YAPPairTerm(YAPTerm th, YAPTerm tl) : YAPTerm() +YAPPairTerm::YAPPairTerm(YAPTerm th, YAPTerm tl) { CACHE_REGS BACKUP_H(); @@ -247,10 +256,10 @@ YAPPairTerm::YAPPairTerm(YAPTerm th, YAPTerm tl) : YAPTerm() RECOVER_H(); } -YAPPairTerm::YAPPairTerm() : YAPTerm() +YAPPairTerm::YAPPairTerm() { BACKUP_H(); - t = Yap_MkNewPairTerm(); + mk(TermNil); RECOVER_H(); } @@ -409,14 +418,13 @@ YAPVarTerm::YAPVarTerm() const char *YAPAtom::getName(void) { return Yap_AtomToUTF8Text(a, nullptr); } -void YAPQuery::openQuery() +void YAPQuery::openQuery(Term t) { CACHE_REGS arity_t arity = ap->ArityOfPE; if (arity) { Term *ts; - Term t = goal; if (IsPairTerm(t)) { ts = RepPair(t); @@ -439,7 +447,7 @@ void YAPQuery::openQuery() q_p = P; q_cp = CP; // make sure this is safe - q_handles = Yap_StartSlots(); + q_handles = LOCAL_CurSlot; } bool YAPEngine::call(YAPPredicate ap, YAPTerm ts[]) @@ -546,6 +554,11 @@ void YAPEngine::release() RECOVER_MACHINE_REGS(); } +YAPTerm YAPEngine::fun(YAPTerm t) +{ + return YAPTerm(fun(t.term())); +} + Term YAPEngine::fun(Term t) { CACHE_REGS @@ -560,6 +573,10 @@ Term YAPEngine::fun(Term t) Atom name; BACKUP_MACHINE_REGS(); + fprintf(stderr," ++++ "); + Yap_DebugPlWriteln(t); + fprintf(stderr," ++++\n"); + t = Yap_StripModule(t, &tmod); if (IsApplTerm(t)) { ts = RepAppl(t) + 1; @@ -585,7 +602,7 @@ Term YAPEngine::fun(Term t) } else { - Yap_Error(TYPE_ERROR_CALLABLE, t, 0); + Yap_ThrowError(TYPE_ERROR_CALLABLE, t, 0); return 0L; } XREGS[arity + 1] = MkVarTerm(); @@ -614,6 +631,7 @@ Term YAPEngine::fun(Term t) Yap_CloseHandles(q.CurSlot); RECOVER_MACHINE_REGS(); return XREGS[arity]; + Yap_DebugPlWriteln(XREGS[arity]); } catch (YAPError e) { @@ -629,9 +647,9 @@ YAPQuery::YAPQuery(YAPFunctor f, YAPTerm mod, YAPTerm ts[]) { /* ignore flags for now */ BACKUP_MACHINE_REGS(); - goal = YAPApplTerm(f, ts).gt(); - names = TermNil; - openQuery(); + goal = YAPApplTerm(f, ts); + names = YAPPairTerm( TermNil ); + openQuery(goal.term()); RECOVER_MACHINE_REGS(); } @@ -639,9 +657,9 @@ YAPQuery::YAPQuery(YAPFunctor f, YAPTerm mod, YAPTerm ts[]) YAPQuery::YAPQuery(YAPFunctor f, YAPTerm ts[]) : YAPPredicate(f) { /* ignore flags for now */ BACKUP_MACHINE_REGS(); - goal = YAPApplTerm(f, ts).gt(); - names = TermNil; - openQuery(); + goal = YAPTerm( YAPApplTerm(f, ts).gt() ); + names.= YAPPairTerm( TermNil ); + openQuery(goal.term()); RECOVER_MACHINE_REGS(); } #endif @@ -649,28 +667,12 @@ YAPQuery::YAPQuery(YAPFunctor f, YAPTerm ts[]) : YAPPredicate(f) { YAPQuery::YAPQuery(YAPPredicate p, YAPTerm ts[]) : YAPPredicate(p.ap) { BACKUP_MACHINE_REGS(); - goal = YAPApplTerm(YAPFunctor(p.ap->FunctorOfPred), ts).term(); - names = TermNil; - openQuery(); + goal = YAPApplTerm(YAPFunctor(p.ap->FunctorOfPred), ts); + names = YAPPairTerm( TermNil ); + openQuery(goal.term()); RECOVER_MACHINE_REGS(); } -Term YAPQuery::namedVars() -{ - CACHE_REGS - __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "vnames %s %ld", - names.text(), LOCAL_CurSlot); - return (names); // should be o -} - -Term YAPQuery::namedVarsCopy() -{ - CACHE_REGS - __android_log_print(NDROID_LOG_INFO, "YAPDroid", "vnames %s %ld", - names.text(), LOCAL_CurSlot); - return (YAP_CopyTerm(names)); // should be o -} - bool YAPQuery::next() { CACHE_REGS @@ -847,9 +849,19 @@ void Yap_displayWithJava(int c) #endif +void YAPEngineArgs::fetch_defaults() +{ + Yap_InitDefaults(&init_args, NULL, 0, NULL); +#if YAP_PYTHON + init_args.Embedded = true; + python_in_python = Py_IsInitialized(); +#endif +} + void YAPEngine::doInit(YAP_file_type_t BootMode) { - if ((BootMode = YAP_Init(&init_args)) == YAP_FOUND_BOOT_ERROR) + + if ((BootMode = YAP_Init(&engine_args.init_args)) == YAP_FOUND_BOOT_ERROR) { throw YAPError(); } @@ -863,6 +875,9 @@ void YAPEngine::doInit(YAP_file_type_t BootMode) #endif yerror = YAPError(); +#ifdef YAP_PYTHON + init_python(); +#endif YAPQuery initq = YAPQuery(YAPAtom("$init_system")); if (initq.next()) { @@ -874,45 +889,21 @@ void YAPEngine::doInit(YAP_file_type_t BootMode) } } -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, bool embedded, - YAPCallback *cb) +YAPEngine::YAPEngine(YAPEngineArgs &argp) : _callback(0) { // a single engine can be active + engine_args = argp; 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; - init_args.MaxStackSize = maxStackSize; - init_args.MaxTrailSize = maxTrailSize; - init_args.YapLibDir = libDir; - init_args.YapPrologBootFile = bootFile; - init_args.YapPrologGoal = goal; - init_args.YapPrologTopLevelGoal = topLevel; - init_args.HaltAfterConsult = script; - init_args.FastBoot = fastBoot; - init_args.Embedded = embedded; + BootMode = engine_args.init_args.boot_file_type; doInit(BootMode); + } YAPEngine::YAPEngine(int argc, char *argv[], @@ -920,8 +911,9 @@ YAPEngine::YAPEngine(int argc, char *argv[], : _callback(0) { // a single engine can be active + engine_args = YAPEngineArgs(); YAP_file_type_t BootMode; - BootMode = YAP_parse_yap_arguments(argc, argv, &init_args); + BootMode = YAP_parse_yap_arguments(argc, argv, &engine_args.init_args); // delYAPCallback()b // if (cb) // setYAPCallback(cb); @@ -950,20 +942,21 @@ YAPPredicate::YAPPredicate(YAPAtom at, uintptr_t arity) } /// auxiliary routine to find a predicate in the current module. -PredEntry *YAPPredicate::getPred(Term &t, Term *&outp) +PredEntry *YAPPredicate::getPred(YAPTerm &tt, Term *&outp) { CACHE_REGS - Term m = Yap_CurrentModule(); + Term m = Yap_CurrentModule(), t = tt.term(); t = Yap_StripModule(t, &m); if (IsVarTerm(t) || IsNumTerm(t)) { if (IsVarTerm(t)) - Yap_Error(INSTANTIATION_ERROR, t, 0); + Yap_ThrowError(INSTANTIATION_ERROR, tt.term(), 0); else if (IsNumTerm(t)) - Yap_Error(TYPE_ERROR_CALLABLE, t, 0); + Yap_ThrowError(TYPE_ERROR_CALLABLE, tt.term(), 0); throw YAPError(); } - if (IsAtomTerm(t)) + tt.put(t); + if (IsAtomTerm(t)) { ap = RepPredProp(PredPropByAtom(AtomOfTerm(t), m)); outp = (Term *)NULL; @@ -975,14 +968,13 @@ PredEntry *YAPPredicate::getPred(Term &t, Term *&outp) ts[0] = t; ts[1] = m; t = Yap_MkApplTerm(FunctorCsult, 2, ts); + tt.put(t); outp = RepAppl(t) + 1; } Functor f = FunctorOfTerm(t); if (IsExtensionFunctor(f)) { - Yap_Error(TYPE_ERROR_CALLABLE, t, 0); - ; - throw YAPError(); + Yap_ThrowError(TYPE_ERROR_CALLABLE, t, 0); } else { diff --git a/CXX/yapi.hh b/CXX/yapi.hh index 6c80daa5f..a4b840ef8 100644 --- a/CXX/yapi.hh +++ b/CXX/yapi.hh @@ -15,15 +15,13 @@ /*! * - * @{ * @ingroup fli_c_cx * @defgroup yap-cplus-interface An object oriented interface for YAP. * - * @tableofcontents + * @{ * * - * @short C++ wrapper to terms, predicates and queries - * + * @brief C++ wrapper to terms, predicates and queries * * This new interface is designed to be object oriented and to fit * naturally with the swig interface language generator. It uses ideas diff --git a/CXX/yapq.hh b/CXX/yapq.hh index fca7d5c77..6e69167a3 100644 --- a/CXX/yapq.hh +++ b/CXX/yapq.hh @@ -1,17 +1,19 @@ + /** * @file yapq.hh - ^ + * * @defgroup yap-cplus-query-hanadlinge Query Handling in the YAP interface. * @brief Engine and Query Management * * @ingroup yap-cplus-interface - * @tableofcontents * * @{ - * - * These classes wrap engine ana of query.Ann engine is an environment where we can rum + * + * These classes wrap engine and query. An engine is an environment where we can rum * Prolog, that is, where we can run queries. * + * Also, supports callbacks and engine configuration. + * */ #ifndef YAPQ_HH @@ -39,11 +41,12 @@ class YAPQuery : public YAPPredicate int q_flags; YAP_dogoalinfo q_h; YAPQuery *oq; - Term names; - Term goal; + YAPPairTerm names; + YAPTerm goal; // temporaries + Term tnames, tgoal ; - void openQuery(); + void openQuery(Term t); public: /// main constructor, uses a predicate and an array of terms @@ -54,6 +57,7 @@ public: YAPQuery(YAPPredicate p, YAPTerm t[]); /// full constructor, /// + /// /// It is given a functor, module, and an array of terms that must have at /// least /// the same arity as the functor. @@ -68,16 +72,16 @@ public: /// 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, goal, names) + inline YAPQuery(const char *s) : YAPPredicate(s, tgoal, tnames) { - BACKUP_H(); __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "got game %ld", LOCAL_CurSlot); if (!ap) return; __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "%s", vnames.text()); - openQuery(); - RECOVER_H(); + goal = YAPTerm(tgoal); + names = YAPPairTerm(tnames); + openQuery(tgoal); }; /// string constructor with just an atom /// @@ -85,9 +89,9 @@ public: /// goal, say `main`, `init`, `live`. inline YAPQuery(YAPAtom g) : YAPPredicate(g) { - goal = YAPAtomTerm(g).gt(); - names = TermNil; - openQuery(); + goal = YAPAtomTerm(g); + names = YAPPairTerm( ); + openQuery(goal.term()); }; /// set flags for query execution, currently only for exception handling @@ -112,9 +116,10 @@ public: void close(); /// query variables. void cut(); - Term namedVars(); + Term namedVars() {return names.term(); }; /// query variables, but copied out - Term namedVarsCopy(); + std::vector namedVarsVector() { + return names.listToArray(); }; /// convert a ref to a binding. YAPTerm getTerm(yhandle_t t); /// simple YAP Query; @@ -141,6 +146,172 @@ public: virtual void run(char *s) {} }; + + class YAPEngine; + +/// @brief Setup all arguments to a new engine +class YAPEngineArgs { + + friend class YAPEngine; + + YAP_init_args init_args; + + void fetch_defaults(); + +public: + + inline void setEmbedded( bool fl ) + { + init_args.Embedded = fl; + }; + + inline bool getEmbedded( ) + { + return init_args.Embedded; + }; + + inline void setSavedState( char *fl ) + { + init_args.SavedState = fl; + }; + + inline const char * getSavedState( ) + { + return init_args.SavedState; + }; + + inline void setStackSize( bool fl ) + { + init_args.StackSize = fl; + }; + + inline bool getStackSize( ) + { + return init_args.StackSize; + }; + + inline void setTrailSize( bool fl ) + { + init_args.TrailSize = fl; + }; + + inline bool getTrailSize( ) + { + return init_args.TrailSize; + }; + + inline bool getMStackSize( ) + { + return init_args.StackSize; + }; + + inline void setMaxTrailSize( bool fl ) + { + init_args.MaxTrailSize = fl; + }; + + inline bool getMaxTrailSize( ) + { + return init_args.MaxTrailSize; + }; + + inline void setYapLibDir( const char * fl ) + { + init_args.YapLibDir = fl; + }; + + inline const char * getYapLibDir( ) + { + return init_args.YapLibDir; + }; + + inline void setYapShareDir( const char * fl ) + { + init_args.YapShareDir = fl; + }; + + inline const char * getYapShareDir( ) + { + return init_args.YapShareDir; + }; + + inline void setYapPrologBootFile( const char * fl ) + { + init_args.YapPrologBootFile = fl; + }; + + inline const char * getYapPrologBootFile( ) + { + return init_args.YapPrologBootFile; + }; + + inline void setYapPrologGoal( const char * fl ) + { + init_args.YapPrologGoal = fl; + }; + + inline const char * getYapPrologGoal( ) + { + return init_args.YapPrologGoal; + }; + + inline void setYapPrologTopLevelGoal( const char * fl ) + { + init_args.YapPrologTopLevelGoal = fl; + }; + + inline const char * getYapPrologTopLevelGoal( ) + { + return init_args.YapPrologTopLevelGoal; + }; + + inline void setHaltAfterConsult( bool fl ) + { + init_args.HaltAfterConsult = fl; + }; + + inline bool getHaltAfterConsult( ) + { + return init_args.HaltAfterConsult; + }; + + inline void setFastBoot( bool fl ) + { + init_args.FastBoot = fl; + }; + + inline bool getFastBoot( ) + { + return init_args.FastBoot; + }; + + inline void setArgc( int fl ) + { + init_args.Argc = fl; + }; + + inline int getArgc( ) + { + return init_args.Argc; + }; + + inline void setArgv( char ** fl ) + { + init_args.Argv = fl; + }; + + inline char ** getArgv( ) + { + return init_args.Argv; + }; + + + YAPEngineArgs() { + fetch_defaults(); + }; + +}; + /** * @brief YAP Engine: takes care of the execution environment where we can go executing goals. @@ -150,23 +321,15 @@ public: class YAPEngine { private: + YAPEngineArgs engine_args; YAPCallback *_callback; - YAP_init_args init_args; YAPError yerror; void doInit(YAP_file_type_t BootMode); YAP_dogoalinfo q; public: /// 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, - bool embedded = true, - YAPCallback *callback = (YAPCallback *) - NULL); /// construct a new engine, including aaccess to callbacks + YAPEngine(YAPEngineArgs &cargs); /// 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); @@ -181,7 +344,7 @@ public: _callback = cb; } /// execute the callback. - ////void run() { if (_callback) _callback->run(); } + ////void run() { if (_callback) _callback.run(); } /// execute the callback with a text argument. void run(char *s) { @@ -213,7 +376,7 @@ public: } /// reset Prolog state void reSet(); - /// release: assune that there are no stack pointers, just release memory + /// assune that there are no stack pointers, just release memory // for last execution void release(); @@ -229,11 +392,13 @@ public: std::string s = Yap_version(); return s.c_str(); }; + //> call a deterninistic predicate: the user will construct aterm of + //> arity N-1. YAP adds an extra variable which will have the + //> output. + YAPTerm fun(YAPTerm t); Term fun(Term t); }; #endif /* YAPQ_HH */ /// @} - - diff --git a/CXX/yapt.hh b/CXX/yapt.hh index 124b1b4a7..f950b5814 100644 --- a/CXX/yapt.hh +++ b/CXX/yapt.hh @@ -13,13 +13,14 @@ * * These classes offer term construction and access. Terms are seens * as objects that inherit from a virtual class, Currently, all - * terms must reside in the stack and may be moved around during + * terms must reside in the stack and may be moved around during * garbage collection. Term objects use an handle, in the SWI-Prolog style. * - * Nottce that terms are forcefully destroyed during backtracking. - * + * Notice that terms are forcefully destroyed during backtracking. + * */ +#include #ifndef YAPT_HH #define YAPT_HH 1 @@ -58,6 +59,11 @@ public: // 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); }; #ifdef SWIGPYTHON // YAPTerm(struct _object *inp) { @@ -68,7 +74,7 @@ public: /// private method to convert from Term (internal YAP representation) to /// YAPTerm // do nothing constructor - YAPTerm() { mk(MkVarTerm()); }; + YAPTerm() { t=0; }; // YAPTerm(yhandle_t i) { t = i; }; /// pointer to term YAPTerm(void *ptr); @@ -82,13 +88,14 @@ public: /// Term destructor, tries to recover slot virtual ~YAPTerm() { // fprintf(stderr,"-%d,%lx,%p ",t,LOCAL_HandleBase[t] ,HR); - if (!t) +/* if (!t) return; Yap_DebugPlWriteln(LOCAL_HandleBase[t]); LOCAL_HandleBase[t] = TermFreeTerm; while (LOCAL_HandleBase[LOCAL_CurSlot - 1] == TermFreeTerm) { LOCAL_CurSlot--; } + */ }; #endif @@ -185,15 +192,19 @@ public: BACKUP_MACHINE_REGS(); Term tf = 0; Term t0 = gt(); - if (IsApplTerm(t0)) + + if (IsApplTerm(t0)) { + if (i > t) YAPError(DOMAIN_ERROR_OUT_OF_RANGE, t0, "t0.getArg()"); tf = (ArgOfTerm(i, t0)); - else if (IsPairTerm(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 { - tf = ((Term)0); + YAPError(TYPE_ERROR_COMPOUND , t0, "t0.getArg()"); } RECOVER_MACHINE_REGS(); return tf; @@ -276,9 +287,9 @@ public: */ class YAPApplTerm : public YAPTerm { friend class YAPTerm; - YAPApplTerm(Term t0) { mk(t0); } public: + YAPApplTerm(Term t0) { mk(t0); } YAPApplTerm(Functor f, Term ts[]) { BACKUP_MACHINE_REGS(); Term t0 = Yap_MkApplTerm(f, f->ArityOfFE, ts); @@ -314,18 +325,36 @@ public: */ class YAPPairTerm : public YAPTerm { friend class YAPTerm; - YAPPairTerm(Term t0) { - if (IsPairTerm(t0)) - mk(t0); - else - mk(0); - } + public: - YAPPairTerm(YAPTerm hd, YAPTerm tl); + 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())); } + std::vector listToArray() { + Term *tailp; + Term t1 = gt(); + Int l = Yap_SkipList(&t1, &tailp); + if (l < 0) { + throw YAPError(TYPE_ERROR_LIST, YAPTerm(t), ""); + } + std::vector o = std::vector(l); + int i = 0; + Term t = gt(); + while (t != TermNil) { + o[i++] = HeadOfTerm(t); + t = TailOfTerm(t); + } + return o; + } }; /** diff --git a/packages/python/CMakeLists.txt b/packages/python/CMakeLists.txt index 6fd891110..49328bef0 100644 --- a/packages/python/CMakeLists.txt +++ b/packages/python/CMakeLists.txt @@ -3,57 +3,50 @@ if (PYTHONLIBS_FOUND) -include(FindPythonModule) + include(FindPythonModule) -set (PYTHON_SOURCES - python.c pl2py.c pybips.c py2pl.c pl2pl.c pypreds.c) + set (PYTHON_SOURCES python.c pl2py.c pybips.c py2pl.c pl2pl.c pypreds.c) -set (PYTHON_HEADERS - python.h) + set (PYTHON_HEADERS python.h) -set (CMAKE_POSITION_INDEPENDENT_CODE TRUE) + set (CMAKE_POSITION_INDEPENDENT_CODE TRUE) -add_library (YAPPython SHARED ${PYTHON_SOURCES}) + add_library (YAPPython SHARED ${PYTHON_SOURCES}) - target_link_libraries(YAPPython libYap ${PYTHON_LIBRARY} - ${WINDLLS} -${GMP_LIBRARIES}) + target_link_libraries(YAPPython libYap ${PYTHON_LIBRARY} ${WINDLLS} ${GMP_LIBRARIES}) + set_property( SOURCE ${PYTHON_SOURCES} APPEND PROPERTY COMPILE_DEFINITIONS YAP_KERNEL=1) -set_property( SOURCE ${PYTHON_SOURCES} APPEND PROPERTY COMPILE_DEFINITIONS YAP_KERNEL=1) + set (PYTHON_PL python.pl) + install(FILES python.pl DESTINATION ${libpl} ) - install(FILES python.pl - DESTINATION ${libpl} - ) - -configure_file ("setup.py.cmake" "setup.py" ) + add_to_group( pl_library PYTHON_PL ) + +# configure_file ("setup.py.cmake" "setup.py" ) set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py") -#set_target_properties (YAPPython PROPERTIES PREFIX "") + #set_target_properties (YAPPython PROPERTIES PREFIX "") + find_python_module( jupyter ) -find_python_module( jupyter ) + if (PY_JUPYTER) -if (PY_JUPYTER) + add_subdirectory(yap_kernel) -add_subdirectory(yap_kernel) + ENDIF() -ENDIF() - - - -IF(WIN32) -install(TARGETS YAPPython - LIBRARY DESTINATION ${dlls} - RUNTIME DESTINATION ${bindir} - ARCHIVE DESTINATION ${dlls} ) -else() - install(TARGETS YAPPython - LIBRARY DESTINATION ${dlls} - RUNTIME DESTINATION ${dlls} - ARCHIVE DESTINATION ${dlls} ) + IF(WIN32) + install(TARGETS YAPPython + LIBRARY DESTINATION ${libdir} + RUNTIME DESTINATION ${bindir} + ARCHIVE DESTINATION ${libdir} ) + else() + install(TARGETS YAPPython + LIBRARY DESTINATION ${libdir} + RUNTIME DESTINATION ${libdir} + ARCHIVE DESTINATION ${libdir} ) endif() endif (PYTHONLIBS_FOUND) diff --git a/packages/python/pl2py.c b/packages/python/pl2py.c index f73c5dafe..2dbc0aa09 100644 --- a/packages/python/pl2py.c +++ b/packages/python/pl2py.c @@ -2,14 +2,14 @@ #include "python.h" -PyObject *py_Local, *py_Global; +extern PyObject *py_Local, *py_Global; PyObject *YE(term_t t, int line, const char *file, const char *code) { char buf[1024]; YAP_WriteBuffer(YAP_GetFromSlot(t), buf, 1023, 0); fprintf(stderr, "**** Warning,%s@%s:%d: failed on expression %s\n", code, file, line, buf ); - + return NULL; } @@ -32,15 +32,16 @@ void YEM(const char * exp, int line, const char *file, const char *code) PyObject *term_to_python(term_t t, bool eval, PyObject *o) { // o≈ YAP_Term yt = YAP_GetFromSlot(t); - // Yap_DebugPlWriteln(yt); + Yap_DebugPlWriteln(yt); switch (PL_term_type(t)) { case PL_VARIABLE: { - YAP_Term i = YAP_MkIntTerm(t); - PyObject *rc = term_to_nametuple( - "H", 1, YAP_InitSlot(YAP_MkApplTerm( - YAP_MkFunctor(YAP_LookupAtom("H"), 1), 1, &i))); - return CHECKNULL( t, rc ); - }; + if (t==0) { + Yap_ThrowError(SYSTEM_ERROR_INTERNAL, yt, "in term_to_python"); + } + PyObject *out = PyTuple_New(1); + PyTuple_SET_ITEM(out, 0, PyLong_FromLong(t)); + return term_to_nametuple("v", 1, out); + }; case PL_ATOM: { YAP_Atom at = YAP_AtomOfTerm(yt); const char *s; @@ -105,7 +106,7 @@ PyObject *term_to_python(term_t t, bool eval, PyObject *o) { term_t tail = PL_new_term_ref(), arg; size_t len, i; if (PL_skip_list(t, tail, &len) && PL_get_nil(tail)) { - PyObject *out; + PyObject *out, *a; arg = tail; out = PyList_New(len); @@ -115,10 +116,14 @@ PyObject *term_to_python(term_t t, bool eval, PyObject *o) { for (i = 0; i < len; i++) { if (!PL_get_list(t, arg, t)) { PL_reset_term_refs(tail); - return CHECKNULL(t,NULL); + return Py_None; } - if (PyList_SetItem(out, i, term_to_python(arg, eval, o)) < 0) { - return CHECKNULL(t,NULL); + a = term_to_python(arg, eval, o); + if (a == NULL) { + a = Py_None; + } + if (PyList_SetItem(out, i, a) < 0) { + return Py_None; } } PL_reset_term_refs(tail); @@ -144,6 +149,8 @@ PyObject *term_to_python(term_t t, bool eval, PyObject *o) { } PyObject *yap_to_python(YAP_Term t, bool eval, PyObject *o) { + if (t==0) + return NULL; term_t yt = YAP_InitSlot(t); o = term_to_python(yt, eval, o); PL_reset_term_refs(yt); diff --git a/packages/python/py2pl.c b/packages/python/py2pl.c index e25d25fea..0fe45324e 100644 --- a/packages/python/py2pl.c +++ b/packages/python/py2pl.c @@ -6,7 +6,6 @@ static foreign_t repr_term(PyObject *pVal, term_t t) { PL_put_pointer(t1, pVal); PL_cons_functor(to, FUNCTOR_pointer1, t1); Py_INCREF(pVal); - PL_reset_term_refs(to); return PL_unify(t, to); } @@ -14,7 +13,6 @@ foreign_t assign_to_symbol(term_t t, PyObject *e); foreign_t assign_to_symbol(term_t t, PyObject *e) { char *s = NULL; - PyErr_Clear(); if (!PL_get_atom_chars(t, &s)) { return false; } @@ -25,58 +23,58 @@ foreign_t assign_to_symbol(term_t t, PyObject *e) { } foreign_t python_to_term(PyObject *pVal, term_t t) { + bool rc = true; + term_t to = PL_new_term_ref(); +fputs(" <<*** ",stderr); PyObject_Print(pVal,stderr,0); fputs("<<***\n",stderr); if (pVal == Py_None) { - return PL_unify_atom(t, ATOM_none); + fputs("<<*** ",stderr);Yap_DebugPlWrite(YAP_GetFromSlot(t)); fputs(" >>***\n",stderr); + rc= PL_unify_atom(t, ATOM_none); fputs("<<*** ",stderr);Yap_DebugPlWrite(YAP_GetFromSlot(t)); fputs(" >>***\n",stderr); } if (PyBool_Check(pVal)) { if (PyObject_IsTrue(pVal)) { - return PL_unify_atom(t, ATOM_true); + rc = PL_unify_atom(t, ATOM_true); } else { - return PL_unify_atom(t, ATOM_false); + rc = PL_unify_atom(t, ATOM_false); } } else if (PyLong_Check(pVal)) { - return PL_unify_int64(t, PyLong_AsLong(pVal)); + rc = PL_unify_int64(t, PyLong_AsLong(pVal)); #if PY_MAJOR_VERSION < 3 } else if (PyInt_Check(pVal)) { - return PL_unify_int64(t, PyInt_AsLong(pVal)); + rc = PL_unify_int64(t, PyInt_AsLong(pVal)); #endif } else if (PyFloat_Check(pVal)) { - return PL_unify_float(t, PyFloat_AsDouble(pVal)); + rc = PL_unify_float(t, PyFloat_AsDouble(pVal)); } else if (PyComplex_Check(pVal)) { - bool rc; - term_t to = PL_new_term_ref(), t1 = PL_new_term_ref(), + term_t t1 = PL_new_term_ref(), t2 = PL_new_term_ref(); if (!PL_put_float(t1, PyComplex_RealAsDouble(pVal)) || !PL_put_float(t2, PyComplex_ImagAsDouble(pVal)) || !PL_cons_functor(to, FUNCTOR_complex2, t1, t2)) { - rc = FALSE; + rc = false; } else { rc = PL_unify(t, to); } - PL_reset_term_refs(to); - return rc; } else if (PyUnicode_Check(pVal)) { atom_t tmp_atom; #if PY_MAJOR_VERSION < 3 - = PyUnicode_GetSize(pVal) + 1; + size_t sz = PyUnicode_GetSize(pVal) + 1; wchar_t *ptr = malloc(sizeof(wchar_t) * sz); sz = PyUnicode_AsWideChar((PyUnicodeObject *)pVal, ptr, sz - 1); - tmp_atom = PL_new_atom_wchars(sz, ptr); + tmp_atom = PL_new_atom_wchars(sz, ptr); free(ptr); - return PL_unify_atom(t, tmp_atom); #else const char *s = PyUnicode_AsUTF8(pVal); - tmp_atom = PL_new_atom( s); - return PL_unify_atom(t, tmp_atom); + tmp_atom = PL_new_atom( s); #endif + rc = PL_unify_atom(t, tmp_atom); } else if (PyByteArray_Check(pVal)) { atom_t tmp_atom = PL_new_atom(PyByteArray_AsString(pVal)); - return PL_unify_atom(t, tmp_atom); + rc = PL_unify_atom(t, tmp_atom); #if PY_MAJOR_VERSION < 3 } else if (PyString_Check(pVal)) { atom_t tmp_atom = PL_new_atom(PyString_AsString(pVal)); - return PL_unify_atom(t, tmp_atom); + rc = PL_unify_atom(t, tmp_atom); #endif } else if (PyTuple_Check(pVal)) { Py_ssize_t i, sz = PyTuple_Size(pVal); @@ -85,13 +83,10 @@ foreign_t python_to_term(PyObject *pVal, term_t t) { if ((s = (Py_TYPE(pVal)->tp_name))) { if (!strcmp(s, "H")) { pVal = PyTuple_GetItem(pVal, 0); - if (PyLong_Check(pVal)) { - return PyLong_AsLong(pVal); -#if PY_MAJOR_VERSION < 3 - } else if (PyInt_Check(pVal)) { - return PyInt_AsLong(pVal); -#endif - } + if (pVal==NULL) { + pVal = Py_None; + PyErr_Clear(); + } } if (s[0] == '$') { char *ns = malloc(strlen(s) + 5); @@ -102,28 +97,44 @@ foreign_t python_to_term(PyObject *pVal, term_t t) { } else { f = PL_new_functor(PL_new_atom(s), sz); } - } else + } else { f = PL_new_functor(ATOM_t, sz); - if (!PL_unify_functor(t, f)) - return FALSE; - term_t to = PL_new_term_ref(); - for (i = 0; i < sz; i++) { - if (!PL_get_arg(i + 1, t, to)) - return FALSE; - if (!python_to_term(PyTuple_GetItem(pVal, i), to)) - return FALSE; } - return true; + if (PL_unify_functor(t, f)) { + rc = true; + for (i = 0; i < sz; i++) { + if (!PL_get_arg(i + 1, t, to)) + rc = false; + PyObject *p = PyTuple_GetItem(pVal, i); + if (p==NULL) { + PyErr_Clear(); + p = Py_None; + } + rc = rc && python_to_term(p, to); + } + } else { + rc = false; + } + fputs(" ||*** ",stderr); Yap_DebugPlWrite(YAP_GetFromSlot(t)); fputs(" ||***\n",stderr); } else if (PyList_Check(pVal)) { - term_t to = PL_new_term_ref(); + YAP_Term yt = YAP_GetFromSlot(t); Py_ssize_t i, sz = PyList_GET_SIZE(pVal); for (i = 0; i < sz; i++) { - if (!PL_unify_list(t, to, t) || - !python_to_term(PyList_GetItem(pVal, i), to)) - return FALSE; + PyObject *obj; + if (!PL_unify_list(t, to, t)) { + rc = false; + break; + } + if ((obj = PyList_GetItem(pVal, i)) == NULL) { + obj = Py_None; + } + rc = rc && python_to_term(obj, to); + } - return PL_unify_nil(t); + rc = rc && PL_unify_nil(t); + fputs("[***] ", stderr); + Yap_DebugPlWrite(yt); fputs("[***]\n", stderr); } else if (PyDict_Check(pVal)) { Py_ssize_t pos = 0; term_t to = PL_new_term_ref(), ti = to; @@ -135,40 +146,39 @@ foreign_t python_to_term(PyObject *pVal, term_t t) { tnew = PL_new_term_ref(); /* do something interesting with the values... */ if (!python_to_term(key, tkey)) { - PL_reset_term_refs(tkey); - return FALSE; + continue; } if (!python_to_term(value, tval)) { - PL_reset_term_refs(tkey); - return FALSE; + continue; } /* reuse */ tint = tkey; if (!PL_cons_functor(tint, FUNCTOR_colon2, tkey, tval)) { - PL_reset_term_refs(tkey); - return FALSE; + rc = false; + continue; } if (--left) { if (!PL_cons_functor(tint, FUNCTOR_comma2, tint, tnew)) PL_reset_term_refs(tkey); - return FALSE; + rc = false; } if (!PL_unify(ti, tint)) { - PL_reset_term_refs(tkey); - return FALSE; - } + rc = false; } ti = tnew; PL_reset_term_refs(tkey); } - return PL_unify(t, to); + rc = PL_unify(t, to); } else { - return repr_term(pVal, t); + rc = repr_term(pVal, t); } + PL_reset_term_refs(to); + return rc; } X_API YAP_Term pythonToYAP(PyObject *pVal) { term_t t = PL_new_term_ref(); - if (!python_to_term(pVal, t)) + if (pVal == NULL || + !python_to_term(pVal, t)) return 0; YAP_Term tt = YAP_GetFromSlot(t); PL_reset_term_refs(t); @@ -222,20 +232,25 @@ bool python_assign(term_t t, PyObject *exp, PyObject *context) { if (PL_skip_list(t, tail, &len) && PL_get_nil(tail)) { // true list - if (PySequence_Check(exp) && PySequence_Length(exp) == len) + bool o = true; + if (PySequence_Check(exp) && PySequence_Length(exp) == len) - for (i = 0; i < len; i++) { - if (!PL_get_list(t, arg, t)) { - PL_reset_term_refs(tail); - return false; - } - if (!python_assign(arg, PySequence_GetItem(exp, i), context)) { - PL_reset_term_refs(tail); - return false; - } - } - PL_reset_term_refs(tail); - return true; + for (i = 0; i < len; i++) { + PyObject *p; + if (!PL_get_list(t, arg, t)) { + PL_reset_term_refs(tail); + o = false; + p = Py_None; + } + if ((p = PySequence_GetItem(exp, i)) == NULL) + p = Py_None; + if (!python_assign(arg, p, context)) { + PL_reset_term_refs(tail); + o = false; + } + } + PL_reset_term_refs(tail); + return o; } else { functor_t fun; @@ -266,6 +281,8 @@ bool python_assign(term_t t, PyObject *exp, PyObject *context) { } if (PyList_Check(i)) { i = PyList_GetItem(i, 0); + if (i==NULL) + i = Py_None; long int j; if (PyList_Check(o)) { #if PY_MAJOR_VERSION < 3 diff --git a/packages/python/pybips.c b/packages/python/pybips.c index 281d3049f..aa259d9e5 100644 --- a/packages/python/pybips.c +++ b/packages/python/pybips.c @@ -15,7 +15,9 @@ static PyObject *finalLookup(PyObject *i, const char *s) { PyObject *rc; if (i == NULL) - return NULL; + return Py_None; + if (strcmp(s,"none") == 0) + return Py_None; if (PyDict_Check(i)) { if ((rc = PyDict_GetItemString(i, s))) return rc; @@ -31,6 +33,8 @@ static PyObject *finalLookup(PyObject *i, const char *s) { } PyObject *PythonLookupSpecial(const char *s) { + if (s == NULL) + return Py_None; if (strcmp(s, "true") == 0) { return Py_True; } @@ -51,7 +55,9 @@ PyObject *PythonLookupSpecial(const char *s) { PyObject *lookupPySymbol(const char *sp, PyObject *pContext, PyObject **duc) { PyObject *out = NULL; if (!sp) - return NULL; + return Py_None; + if (strcmp(sp, "none") == 0) + return Py_None; if ((out = finalLookup(pContext, sp))) { return out; } @@ -64,7 +70,7 @@ PyObject *lookupPySymbol(const char *sp, PyObject *pContext, PyObject **duc) { } PyObject *py_Local = PyEval_GetLocals(); if ((out = finalLookup(py_Local, sp))) { - return out; + return out; } PyObject *py_Global = PyEval_GetGlobals(); if ((out = finalLookup(py_Global, sp))) { @@ -76,7 +82,7 @@ PyObject *lookupPySymbol(const char *sp, PyObject *pContext, PyObject **duc) { if ((out = finalLookup(py_Main, sp))) { return out; } - return NULL; + return Py_None; } int lookupPyModule(Py_mod *q) { @@ -120,10 +126,10 @@ PyObject *find_obj(PyObject *ob, term_t l, bool eval) { yt = YAP_GetFromSlot(l); while (YAP_IsPairTerm(yt)) { hd = YAP_HeadOfTerm(yt); - ob = yap_to_python(hd, true, ob); + ob = yap_to_python(hd, eval, ob); ob = CHECKNULL(yt, ob); if (!ob){ - return NULL; + return Py_None; } yt = YAP_TailOfTerm(yt); @@ -155,7 +161,7 @@ static PyObject *bip_abs(term_t t) { * Python all * * @param t Prolog term with a previously constructed Python iterator - * +> * * @return the Python boolean `True` if all elements of the iterator are `True`, * `False` otherwise. */ @@ -169,14 +175,14 @@ static PyObject *bip_all(term_t t) { v = CHECKNULL( t, v); it = PyObject_GetIter(v); if (CHECKNULL( t, it) == NULL) - return NULL; + return Py_None; iternext = *Py_TYPE(it)->tp_iternext; if (PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_StopIteration)) PyErr_Clear(); else - return NULL; + return Py_None; } // PyObject_Print(v, stderr, 0); for (;;) { @@ -215,7 +221,7 @@ static PyObject *bip_any(term_t t) { v = term_to_python(t, true, NULL); it = PyObject_GetIter(v); if (CHECKNULL(t,it) == NULL) - return NULL; + return Py_None; iternext = *Py_TYPE(it)->tp_iternext; for (;;) { @@ -265,7 +271,7 @@ static PyObject *bip_float(term_t t, bool eval) { } else if (PyFloat_Check(pVal)) { return pVal; } else - return NULL; + return Py_None; Py_DECREF(pVal); return o; } @@ -291,7 +297,7 @@ static PyObject *bip_int(term_t t) { o = PyLong_FromDouble(PyFloat_AsDouble(pVal)); #endif } else - return NULL; + return Py_None; Py_DECREF(pVal); return o; } @@ -310,7 +316,7 @@ static PyObject *bip_long(term_t t) { } else if (PyFloat_Check(pVal)) { o = pVal; } else - return NULL; + return Py_None; Py_DECREF(pVal); return o; } @@ -344,19 +350,19 @@ static PyObject *bip_ord(term_t t) { return PyLong_FromLong(ord); #endif } - return NULL; + return Py_None; } else if (PyByteArray_Check(pVal)) { char *s = PyByteArray_AsString(pVal); if (s[1]) - return NULL; + return Py_None; #if PY_MAJOR_VERSION < 3 return PyInt_FromLong(s[0]); } else if (PyString_Check(pVal)) { char *s = PyString_AsString(pVal); if (s[1]) - return NULL; + return Py_None; return PyInt_FromLong(s[0]); #else return PyLong_FromLong(s[0]); @@ -477,7 +483,7 @@ static PyObject *bip_sum(term_t t) { } #if PY_MAJOR_VERSION < 3 if (PyInt_CheckExact(item)) { - PyFPE_START_PROTECT("add", Py_DECREF(item); Py_DECREF(iter); return 0) + 764PyFPE_START_PROTECT("add", Py_DECREF(item); Py_DECREF(iter); return 0) f_result += (double)PyInt_AS_LONG(item); PyFPE_END_PROTECT(f_result) Py_DECREF(item); continue; @@ -580,7 +586,7 @@ static long get_len_of_range(long lo, long hi, long step) { return n; } -#if PY_MAJOR_VERSION >= 3 && defined(USE_NAMEDTUPLES) +#if PY_MAJOR_VERSION >= 3 static PyStructSequence_Field pnull[] = { {"A1", NULL}, {"A2", NULL}, {"A3", NULL}, {"A4", NULL}, {"A5", NULL}, {"A6", NULL}, {"A7", NULL}, {"A8", NULL}, @@ -719,9 +725,9 @@ static PyObject *structseq_repr(PyObject *iobj) { } #endif -PyObject *term_to_nametuple(const char *s, int arity, term_t t) { +PyObject *term_to_nametuple(const char *s, arity_t arity, PyObject *tuple) { PyObject *o; -#if PY_MAJOR_VERSION >= 3 && 0 +#if PY_MAJOR_VERSION >= 3 PyTypeObject *typp; PyObject *key = PyUnicode_FromString(s); if (py_F2P && PyDict_Contains(py_F2P, key)) { @@ -748,36 +754,21 @@ PyObject *term_to_nametuple(const char *s, int arity, term_t t) { if (py_F2P) PyDict_SetItem(py_F2P, key, (PyObject *)typp); } -#endif - o = PyTuple_New(arity); - DebugPrintf("Tuple %p\n", o); - if (o == NULL) - return o; - term_t tleft = PL_new_term_ref(); - int i; - - for (i = 0; i < arity; i++) { - PyObject *pArg; - if (!PL_get_arg(i + 1, t, tleft)) - return NULL; - pArg = term_to_python(tleft, false, NULL ); - if (CHECKNULL(tleft,pArg)) - return NULL; -#if PY_MAJOR_VERSION >= 3 - /* pArg reference stolen here: */ - Py_INCREF(pArg); + o = PyStructSequence_New(typp); +for (arity_t i = 0; i < arity; i++) { + PyObject *pArg = PyTuple_GET_ITEM(tuple, i); + if (pArg) PyStructSequence_SET_ITEM(o, i, pArg); + PyObject_Print(pArg,stderr,0);fputc('\n',stderr); } ((PyStructSequence *)o)->ob_base.ob_size = arity; + PyObject_Print(o,stderr,0);fputc('\n',stderr); return o; #else - /* pArg reference stolen here: */ - PyTuple_SET_ITEM(o, i, pArg); - } PyObject *o1; o1 = PyTuple_New(2); PyTuple_SET_ITEM(o1, 0, PyUnicode_FromString(s)); - PyTuple_SET_ITEM(o1, 1, o); + PyTuple_SET_ITEM(o1, 1, tuple); return o1; #endif } @@ -820,7 +811,7 @@ static PyObject *bip_range(term_t t) { v = PyList_New(n); if (v == NULL) - return NULL; + return Py_None; for (i = 0; i < n; i++) { #if PY_MAJOR_VERSION < 3 PyObject *w = PyInt_FromLong(ilow); @@ -959,6 +950,8 @@ PyObject *compound_to_data(term_t t, PyObject *o, functor_t fun, bool exec) { #else if (PyLong_Check(ip)) { PyObject *o = PySequence_GetItem(v, PyLong_AsLong(ip)); + if (o == NULL) + o = Py_None; if (CHECKNULL(t,o) == NULL) return NULL; Py_INCREF(o); @@ -967,6 +960,8 @@ PyObject *compound_to_data(term_t t, PyObject *o, functor_t fun, bool exec) { #endif } else { o = PyObject_GetItem(v, ip); + if (o == NULL) + o = Py_None; Py_INCREF(o); return o; } @@ -1073,20 +1068,32 @@ PyObject *compound_to_pytree(term_t t, PyObject *context) { } term_t tleft; int i; - o = PyTuple_New(arity); + PyObject *out = PyTuple_New(arity); DebugPrintf("Tuple %p\n", o); tleft = PL_new_term_ref(); for (i = 0; i < arity; i++) { PyObject *pArg; AOK (PL_get_arg(i + 1, t, tleft), NULL ); pArg = term_to_python(tleft, false, NULL); - if (pArg == NULL) - return NULL; + if (pArg) { /* pArg reference stolen here: */ - PyTuple_SET_ITEM(o, i, pArg); + PyTuple_SET_ITEM(out, i, pArg); Py_INCREF(pArg); + } } - return term_to_nametuple(s, arity, t); + if (CHECKNULL(t, out) == NULL) { + PyErr_Print(); + return NULL; + } + PyObject *c = lookupPySymbol(s, o, NULL); + + if ( c && PyCallable_Check(c)) { + PyObject *n = PyTuple_New(arity); + PyTuple_SET_ITEM(n, 0, c); + PyTuple_SET_ITEM(n, 1, out); + return n; + } + return term_to_nametuple(s, arity, out); } } @@ -1218,9 +1225,6 @@ PyObject *compound_to_pyeval(term_t t, PyObject *context) { PyErr_Print(); return NULL; } - if ( !PyCallable_Check(o)) { - return term_to_nametuple(s, arity, t); - } PyObject *pArgs = PyTuple_New(arity); DebugPrintf("Tuple %p\n", pArgs); int i; @@ -1230,16 +1234,23 @@ PyObject *compound_to_pyeval(term_t t, PyObject *context) { AOK (PL_get_arg(i + 1, t, tleft), NULL ); /* ignore (_) */ if (i == 0 && PL_is_variable(tleft)) { - Py_DECREF(pArgs); - pArgs = Py_None; + pArg = Py_None; + } else { + pArg = term_to_python(tleft, true, NULL); + PyObject_Print(pArg,fdopen(2,"w"),0); + if (pArg == NULL) { + pArg = Py_None; + } + /* pArg reference stolen here: */ + Py_INCREF(pArg); } - pArg = term_to_python(tleft, true, NULL); - pArg = CHECKNULL( tleft, pArg ); - /* pArg reference stolen here: */ - Py_INCREF(pArg); + PyTuple_SetItem(pArgs, i, pArg); } - PyObject *rc; + if ( !PyCallable_Check(o)) { + return term_to_nametuple(s, arity, pArgs); + } +PyObject *rc; //PyObject_Print(pArgs, stderr, 0); //PyObject_Print(o, stderr, 0); diff --git a/packages/python/python.c b/packages/python/python.c index 130fc0745..1d6e30a3e 100644 --- a/packages/python/python.c +++ b/packages/python/python.c @@ -23,6 +23,23 @@ X_API PyObject *py_F2P; bool python_in_python; +static void add_modules(void) { + py_Main = PyImport_AddModule("__main__"); + Py_INCREF(py_Main); + py_Sys = PyImport_AddModule("sys"); + Py_INCREF(py_Sys); + py_Builtin = PyImport_AddModule("__builtin__"); + Py_INCREF(py_Builtin); + py_ModDict = PyObject_GetAttrString(py_Sys, "modules"); + // py_Yapex = PyImport_ImportModule("yap4py.yapi"); + // PyObject *py_Yap = + PyImport_ImportModule("yap"); + if (py_Yapex) + Py_INCREF(py_Yapex); + //py_F2P = PyObject_GetAttrString(py_Yap, "globals"); + py_F2P = NULL; +} + static void install_py_constants(void) { FUNCTOR_dot2 = PL_new_functor(PL_new_atom("."), 2); // FUNCTOR_equal2 = PL_new_functor(PL_new_atom("="), 2); @@ -35,7 +52,6 @@ static void install_py_constants(void) { ATOM_true = PL_new_atom("true"); ATOM_false = PL_new_atom("false"); ATOM_dot = PL_new_atom("."); - ATOM_none = PL_new_atom("none"); ATOM_self = PL_new_atom("self"); ATOM_t = PL_new_atom("t"); FUNCTOR_abs1 = PL_new_functor(PL_new_atom("abs"), 1); @@ -68,24 +84,11 @@ static void install_py_constants(void) { FUNCTOR_comma2 = PL_new_functor(PL_new_atom(","), 2); FUNCTOR_equal2 = PL_new_functor(PL_new_atom("="), 2); FUNCTOR_sqbrackets2 = PL_new_functor(PL_new_atom("[]"), 2); - // if (python_in_python) { - py_Main = PyImport_AddModule("__main__"); - Py_INCREF(py_Main); - py_Sys = PyImport_AddModule("sys"); - Py_INCREF(py_Sys); - py_Builtin = PyImport_AddModule("__builtin__"); - Py_INCREF(py_Builtin); - py_ModDict = PyObject_GetAttrString(py_Sys, "modules"); - py_Yapex = PyImport_ImportModule("yapex"); - // PyObject *py_Yap = - PyImport_ImportModule("yap"); - Py_INCREF(py_Yapex); - //py_F2P = PyObject_GetAttrString(py_Yap, "globals"); - py_F2P = NULL; -} + } foreign_t end_python(void) { - Py_Finalize(); + if (!python_in_python) + Py_Finalize(); return true; } @@ -100,12 +103,14 @@ bool do_init_python(void) { libpython_initialized = true; // PyGILState_STATE gstate = PyGILState_Ensure(); term_t t = PL_new_term_ref(); - Py_Initialize(); + if (!python_in_python) + Py_Initialize(); install_py_constants(); PL_reset_term_refs(t); install_pypreds(); install_pl2pl(); // PyGILState_Release(gstate); + add_modules(); return !python_in_python; } diff --git a/packages/python/python.h b/packages/python/python.h index 1ff1be427..583ad841e 100644 --- a/packages/python/python.h +++ b/packages/python/python.h @@ -133,7 +133,7 @@ static inline PyObject *atom_to_python_string(term_t t) { YE(t,__LINE__,__FILE__,__FUNCTION__);\ PyErr_Print(); PyErr_Clear();\ } - + #define CHECKNULL(t,rc) (rc != NULL ? rc : YE(t,__LINE__,__FILE__,__FUNCTION__) ) #define AOK(rc, err) { if (!rc) YEM( #rc ,__LINE__,__FILE__,__FUNCTION__); } @@ -165,7 +165,7 @@ extern PyObject *compound_to_pytree(term_t t, PyObject *context); extern PyObject *term_to_python(term_t t, bool eval, PyObject *contextxs); -extern PyObject *term_to_nametuple(const char *s, int arity, term_t t); +extern PyObject *term_to_nametuple(const char *s, arity_t arity, PyObject *); extern foreign_t python_to_term(PyObject *pVal, term_t t); extern bool python_assign(term_t t, PyObject *exp, PyObject *context); diff --git a/packages/python/yap_kernel/setup.py.cmake b/packages/python/yap_kernel/setup.py.cmake index 69418dd25..5eec55c59 100644 --- a/packages/python/yap_kernel/setup.py.cmake +++ b/packages/python/yap_kernel/setup.py.cmake @@ -39,7 +39,7 @@ setup_args = dict( name = 'yap_kernel', version = '0.0.1', packages = ["yap_kernel"], - package_dir = {'': '${CMAKE_SOURCE_DIR}/packages/python' }, + package_dir = {'': '${CMAKE_SOURCE_DIR}/packages/python/yap_kernel' }, description = "YAP Kernel for Jupyter", long_description="A simple YAP kernel for Jupyter/IPython", url="https://github.com/vscosta/yap-6.3", diff --git a/packages/python/yapex.py b/packages/python/yapex.py deleted file mode 100644 index 5329de897..000000000 --- a/packages/python/yapex.py +++ /dev/null @@ -1,101 +0,0 @@ - -import yap -import sys -# debugging support. -import pdb - -def query_prolog(engine, s): - - def answer(q): - try: - return q.next() - except Exception as e: - print(e.args[1]) - return False - - # - #construct a query from a one-line string - # q is opaque to Python - q = engine.query(s) - # vs is the list of variables - # you can print it out, the left-side is the variable name, - # the right side wraps a handle to a variable - vs = q.namedVars() - # atom match either symbols, or if no symbol exists, sttrings, In this case - # variable names should match strings - for eq in vs: - if not isinstance(eq[0],str): - print( "Error: Variable Name matches a Python Symbol") - return - ask = True - # launch the query - while answer(q): - # this new vs should contain bindings to vars - vs= q.namedVars() - #numbervars - i=0 - # iteratw - for eq in vs: - name = eq[0] - # this is tricky, we're going to bind the variables in the term so thay we can - # output X=Y. The Python way is to use dictionares. - #Instead, we use the T function to tranform the Python term back to Prolog - binding = yap.T(eq[1]) - if binding.isVar(): - binding.unify(name) - else: - i = binding.numberVars(i, True) - print(name + " = " + binding.text()) - #ok, that was Prolog code - print("yes") - # deterministic = one solution - if q.deterministic(): - # done - q.close() - return - if ask: - s = input("more(;), all(*), no(\\n), python(#) ?").lstrip() - if s.startswith(';') or s.startswith('y'): - continue - elif s.startswith('#'): - try: - exec(s.lstrip('#')) - except: - raise - elif s.startswith('*') or s.startswith('a'): - ask = False - continue - else: - break - print("No (more) answers") - q.close() - return - - -def live(): - engine = yap.YAPEngine() - loop = True - pdb.set_trace() - while loop: - try: - s = input("?- ") - if not s: - loop = False - query_prolog(engine, s) - except SyntaxError as err: - print("Syntax Error error: {0}".format(err)) - except EOFError: - return - except RuntimeError as err: - print("YAP Execution Error: {0}".format(err)) - except ValueError: - print("Could not convert data to an integer.") - except: - print("Unexpected error:", sys.exc_info()[0]) - raise - engine.close() -# -# initialize engine -# engine = yap.YAPEngine(); -# engine = yap.YAPEngine(yap.YAPParams()); -#live() diff --git a/packages/swig/python/CMakeLists.txt b/packages/swig/python/CMakeLists.txt index 8f25949c3..1c75eb540 100644 --- a/packages/swig/python/CMakeLists.txt +++ b/packages/swig/python/CMakeLists.txt @@ -1,83 +1,111 @@ - # This is a CMake example for Python +# This is a CMake example for Python - INCLUDE( NewUseSWIG ) +INCLUDE(NewUseSWIG) - if (PYTHONLIBS_FOUND) +if (PYTHONLIBS_FOUND) - include(FindPythonModule) + include(FindPythonModule) + file(RELATIVE_PATH RELATIVE_SOURCE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}) + INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH}) - INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH}) + INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/CXX") - INCLUDE_DIRECTORIES( "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/CXX" ) + SET_SOURCE_FILES_PROPERTIES(../yap.i PROPERTIES CPLUSPLUS ON) + SET_SOURCE_FILES_PROPERTIES(../yap.i PROPERTIES SWIG_FLAGS "-O;-py3") + SET_SOURCE_FILES_PROPERTIES(../yap.i PROPERTIES SWIG_MODULE_NAME yap) + SET_SOURCE_FILES_PROPERTIES(../yap.i PROPERTIES OUTPUT_NAME yap) - SET_SOURCE_FILES_PROPERTIES(../yap.i PROPERTIES CPLUSPLUS ON) - SET_SOURCE_FILES_PROPERTIES(../yap.i PROPERTIES SWIG_FLAGS "-O;-py3") - SET_SOURCE_FILES_PROPERTIES(../yap.i PROPERTIES SWIG_MODULE_NAME yap ) - SET_SOURCE_FILES_PROPERTIES(../yap.i PROPERTIES OUTPUT_NAME yap ) - - configure_file ("setup.py.cmake" ${CMAKE_CURRENT_BINARY_DIR}/setup.py ) - # configure_file ("../yap.i" "yap.i" ) - - SWIG_ADD_LIBRARY(Py2YAP LANGUAGE python SHARED SOURCES ../yap.i ) - if (WIN32) - SWIG_LINK_LIBRARIES(Py2YAP YAPPython libYap ${PYTHON_LIBRARIES} ) - else() - SWIG_LINK_LIBRARIES( Py2YAP libYap YAP++ YAPPython ${PYTHON_LIBRARIES} ) - endif() + SWIG_ADD_LIBRARY(Py2YAP LANGUAGE python SHARED SOURCES ../yap.i ) + if (WIN32) + SWIG_LINK_LIBRARIES(Py2YAP YAPPython libYap ${PYTHON_LIBRARIES} ) + else() + SWIG_LINK_LIBRARIES( Py2YAP libYap YAP++ YAPPython ${PYTHON_LIBRARIES} ) + endif() set_target_properties ( ${SWIG_MODULE_Py2YAP_REAL_NAME} PROPERTIES - NO_SONAME ON - OUTPUT_NAME _yap - LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" ) - # inform we are compiling YAP - # s used in MSYS + NO_SONAME ON + OUTPUT_NAME _yap + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" ) + # inform we are compiling YAP + # s used in MSYS - execute_process ( COMMAND ${PYTHON_EXECUTABLE} -c "import sysconfig; print( sysconfig.get_path( 'platlib' ) )" - OUTPUT_VARIABLE _ABS_PYTHON_MODULE_PATH - OUTPUT_STRIP_TRAILING_WHITESPACE ) - get_filename_component ( ABS_PYTHON_MODULE_PATH ${_ABS_PYTHON_MODULE_PATH} ABSOLUTE ) - file ( RELATIVE_PATH _REL_PYTHON_MODULE_PATH ${CMAKE_INSTALL_PREFIX} ${_ABS_PYTHON_MODULE_PATH} ) + execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import sysconfig; print( sysconfig.get_path( 'platlib' ) )" + OUTPUT_VARIABLE _ABS_PYTHON_MODULE_PATH + OUTPUT_STRIP_TRAILING_WHITESPACE) + configure_file("setup.py.cmake" ${CMAKE_CURRENT_BINARY_DIR}/setup.py) - set ( PYTHON_MODULE_PATH - ${ABS_PYTHON_MODULE_PATH} - ) + get_filename_component(ABS_PYTHON_MODULE_PATH ${_ABS_PYTHON_MODULE_PATH} ABSOLUTE) + file(RELATIVE_PATH _REL_PYTHON_MODULE_PATH ${CMAKE_INSTALL_PREFIX} ${_ABS_PYTHON_MODULE_PATH}) + # + # set ( PYTHON_MODULE_PATH + # ${ABS_PYTHON_MODULE_PATH} + # ) + # + # INSTALL ( FILES ${CMAKE_CURRENT_BINARY_DIR}/yap.py DESTINATION ${PYTHON_MODULE_PATH} ) + # INSTALL ( FILES ${CMAKE_CURRENT_SOURCE_DIR}/yapi.py DESTINATION ${PYTHON_MODULE_PATH} ) + # INSTALL ( FILES ${CMAKE_CURRENT_SOURCE_DIR}/yapi.yap DESTINATION ${libpl} ) + # + # + # INSTALL ( TARGETS ${SWIG_MODULE_Py2YAP_REAL_NAME} + # RUNTIME DESTINATION ${PYTHON_MODULE_PATH} + # ARCHIVE DESTINATION ${PYTHON_MODULE_PATH} + # LIBRARY DESTINATION ${PYTHON_MODULE_PATH} + # ) + add_custom_target(Py2YAP ALL + DEPENDS ../yap.i libYap YAP++ YAPPython _Py2YAP + ) - INSTALL ( FILES ${CMAKE_CURRENT_BINARY_DIR}/yap.py DESTINATION ${PYTHON_MODULE_PATH} ) - INSTALL ( FILES ${CMAKE_SOURCE_DIR}/packages/python/yapex.py DESTINATION ${PYTHON_MODULE_PATH} ) +set (dlls $ +$ +$ +$ +$ +$ +$) +if (TARGET real) + list( APPEND dlls $ + ) +endif() + add_custom_command(TARGET Py2YAP + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory yap4py/os + COMMAND ${CMAKE_COMMAND} -E make_directory yap4py/pl + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/__init__.py ${dlls} $ $ $ ${CMAKE_CURRENT_SOURCE_DIR}/yapi.yap ${pl_library} ${CMAKE_CURRENT_BINARY_DIR}/yap4py + COMMAND ${CMAKE_COMMAND} -E copy ${pl_os_library} ${CMAKE_CURRENT_BINARY_DIR}/yap4py/os + COMMAND ${CMAKE_COMMAND} -E copy ${pl_boot_library} ${CMAKE_CURRENT_BINARY_DIR}/yap4py/pl + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/README.md ${CMAKE_CURRENT_SOURCE_DIR}/MANIFEST.in ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/yapi.py ${CMAKE_CURRENT_BINARY_DIR}/yap4py - INSTALL ( TARGETS ${SWIG_MODULE_Py2YAP_REAL_NAME} - RUNTIME DESTINATION ${PYTHON_MODULE_PATH} - ARCHIVE DESTINATION ${PYTHON_MODULE_PATH} - LIBRARY DESTINATION ${PYTHON_MODULE_PATH} - ) + COMMAND ${PYTHON_EXECUTABLE} setup.py sdist bdist_wheel + VERBATIM + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + if (WITH_DOCS AND DOXYGEN_FOUND) + set(CMAKE_SWIG_FLAGS -DDOXYGEN=${DOXYGEN_FOUND}) - if ( DOCUMENTATION AND DOXYGEN_FOUND ) + # Run doxygen to only generate the xml + add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/doc/xml/ftdi_8c.xml + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/doc + COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/Doxyfile.xml + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + DEPENDS ${c_headers};${c_sources};${cpp_sources};${cpp_headers} + ) - set(CMAKE_SWIG_FLAGS -DDOXYGEN=${DOXYGEN_FOUND}) + # generate .i from doxygen .xml + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ftdi1_doc.i + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/doxy2swig.py -n + ${CMAKE_BINARY_DIR}/doc/xml/ftdi_8c.xml + ${CMAKE_CURRENT_BINARY_DIR}/ftdi1_doc.i + DEPENDS ${CMAKE_BINARY_DIR}/doc/xml/ftdi_8c.xml + ) + add_custom_target(doc_i DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/ftdi1_doc.i) + add_dependencies(${SWIG_MODULE_ftdi1_REAL_NAME} doc_i) - # Run doxygen to only generate the xml - add_custom_command ( OUTPUT ${CMAKE_BINARY_DIR}/doc/xml/ftdi_8c.xml - COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/doc - COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/Doxyfile.xml - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - DEPENDS ${c_headers};${c_sources};${cpp_sources};${cpp_headers} - ) - - # generate .i from doxygen .xml - add_custom_command ( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ftdi1_doc.i - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/doxy2swig.py -n - ${CMAKE_BINARY_DIR}/doc/xml/ftdi_8c.xml - ${CMAKE_CURRENT_BINARY_DIR}/ftdi1_doc.i - DEPENDS ${CMAKE_BINARY_DIR}/doc/xml/ftdi_8c.xml - ) - add_custom_target ( doc_i DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/ftdi1_doc.i ) - add_dependencies( ${SWIG_MODULE_ftdi1_REAL_NAME} doc_i ) - - ENDIF() - ENDIF() + ENDIF () +ENDIF () diff --git a/packages/swig/python/__init__.py b/packages/swig/python/__init__.py new file mode 100644 index 000000000..aa2bffb4b --- /dev/null +++ b/packages/swig/python/__init__.py @@ -0,0 +1,17 @@ +import imp +import os +import ctypes +import glob +import os.path +import sys + +global yap_lib_path +yap_lib_path = os.path.dirname(__file__) + + +def load( dll ): + dll = glob.glob(os.path.join(yap_lib_path,dll))[0] + dll = os.path.abspath(dll) + ctypes.CDLL(dll, mode=ctypes.RTLD_GLOBAL) + +load('libYap*') diff --git a/packages/swig/python/__main__.py b/packages/swig/python/__main__.py new file mode 100644 index 000000000..7ba19d1a8 --- /dev/null +++ b/packages/swig/python/__main__.py @@ -0,0 +1,14 @@ +"""The main routine of the yap python project.""" + +import sys +import yapi + + +def main(args=None): + """The main routine.""" + if args is None: + args = sys.argv[1:] + yap.yapi.live(args) + +if __name__ == "__main__": + main() diff --git a/packages/swig/python/setup.py.cmake b/packages/swig/python/setup.py.cmake index ecc279e8e..a86e4ddbd 100644 --- a/packages/swig/python/setup.py.cmake +++ b/packages/swig/python/setup.py.cmake @@ -1,38 +1,97 @@ -from distutils.core import setup, Extension -import sys -import os -import platform +"""A setuptools based setup module. +See: +https://packaging.python.org/en/latest/distributing.html +https://github.com/pypa/sampleproject +""" + +# Always prefer setuptools over distutils +from setuptools import setup +from setuptools.extension import Extension +# To use a consistent encoding +from codecs import open +from os import path, makedirs, walk +from shutil import copytree, rmtree, copy2, move +from glob import glob +from pathlib import Path +import platform +import os.path + +my_extra_link_args = [] if platform.system() == 'Darwin': - my_extra_link_args = ['-Wl,-rpath','-Wl,${dlls}'] -else: - my_extra_link_args = [] - -python_sources = ['${CMAKE_CURRENT_SOURCE_DIR}/../yap.i'] + my_extra_link_args = ['-Wl,-rpath','-Wl,${_ABS_PYTHON_MODULE_PATH}'] + so = 'dylib' +#or dll in glob('yap/dlls/*'): +# move( dll ,'lib' ) +pls = [] +for (r,d,fs) in walk('yap/pl'): + for f in fs: + pls += [os.path.join(r, f)] +for (r,d,fs) in walk('yap'): + for f in fs: + pls += [os.path.join(r, f)] +# for f in glob( 'lib*.*' ): +# ofile.write(f+"\n") +cplus=['${RELATIVE_SOURCE}CXX/yapi.cpp'] +py2yap=['${RELATIVE_SOURCE}packages/python/python.c', + '${RELATIVE_SOURCE}packages/python/pl2py.c', + '${RELATIVE_SOURCE}packages/python/pybips.c', + '${RELATIVE_SOURCE}packages/python/py2pl.c', + '${RELATIVE_SOURCE}packages/python/pl2pl.c', + '${RELATIVE_SOURCE}packages/python/pypreds.c' +] +python_sources = ['yapPYTHON_wrap.cxx']+py2yap+cplus +here = path.abspath(path.dirname(__file__)) + +# Get the long description from the README file + +extensions=[Extension('_yap', python_sources, + define_macros = [('MAJOR_VERSION', '1'), + ('MINOR_VERSION', '0'), + ('_YAP_NOT_INSTALLED_', '1'), + ('YAP_PYTHON', '1')], + runtime_library_dirs=['yap4py','${libdir}','${bindir}'], + swig_opts=['-modern', '-c++', '-py3','-I${RELATIVE_SOURCE}/CXX'], + library_dirs=['../../..','../../../CXX','../../packages/python',"${dlls}","${bindir}", '.'], + extra_link_args=my_extra_link_args, + extra_compile_args=['-g'], + libraries=['Yap','${GMP_LIBRARIES}'], + include_dirs=['../../..', + '${GMP_INCLUDE_DIRS}', + '${RELATIVE_SOURCE}H', + '${RELATIVE_SOURCE}H/generated', + '${RELATIVE_SOURCE}OPTYap', + '${RELATIVE_SOURCE}os', + '${RELATIVE_SOURCE}include', + '${RELATIVE_SOURCE}CXX', '.'] +)] setup( - name = "yap", - version = "0.1", -ext_modules=[Extension('_yap', python_sources, - define_macros = [('MAJOR_VERSION', '1'), - ('MINOR_VERSION', '0'), - ('_YAP_NOT_INSTALLED_', '1'), - ('YAP_PYTHON', '1')], - runtime_library_dirs=[,'$(bindir)'], - swig_opts=['-modern','-outcurrentdir', '-c++', '-py3','-I${CMAKE_SOURCE_DIR}/CXX'], - library_dirs=["${dlls}","${bindir}", - '.'], - extra_link_args=my_extra_link_args, - libraries=['Yap','{GMP_LIBRARIES}'], - include_dirs=['../../..', - '${GMP_INCLUDE_DIRS}', - '${CMAKE_SOURCE_DIR}/H', - '${CMAKE_SOURCE_DIR}/H/generated', - '${CMAKE_SOURCE_DIR}/OPTYap', - '${CMAKE_SOURCE_DIR}/os', - '${CMAKE_SOURCE_DIR}/include', - '${CMAKE_SOURCE_DIR}/CXX', '.'] - )], -py_modules = ['yap', '${CMAKE_SOURCE_DIR}/packages/python/yapex'] + name='YAP4Py', + version='${YAP_FULL_VERSION}', + description='The YAP Prolog compiler as a Python Library', + url='https://github.com/vscosta/yap-6.3', + author='Vitor Santos Costa', + author_email='vsc@dcc.fc.up.pt', + license='Artistic', + classifiers=[ + 'Development Status :: 4 - Beta', + 'Intended Audience :: Developers', + 'Topic :: Software Development :: Build Tools', + 'License :: OSI Approved :: Artistic License', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7'], + keywords=['Logic Programing'], + #spackage_data={'': ['yap']}, + include_package_data=True, + ext_modules = extensions, + py_modules = ['yap'], + zip_safe=False, + eager_resources = ['yap4py'], + packages=['yap4py'] # find_packages() +#package_dir = {'':'yap4py'} ) - diff --git a/packages/swig/python/yap.egg-info/PKG-INFO b/packages/swig/python/yap.egg-info/PKG-INFO deleted file mode 100644 index adac5486d..000000000 --- a/packages/swig/python/yap.egg-info/PKG-INFO +++ /dev/null @@ -1,10 +0,0 @@ -Metadata-Version: 1.0 -Name: yap -Version: 0.1 -Summary: UNKNOWN -Home-page: UNKNOWN -Author: UNKNOWN -Author-email: UNKNOWN -License: UNKNOWN -Description: UNKNOWN -Platform: UNKNOWN diff --git a/packages/swig/python/yap.egg-info/SOURCES.txt b/packages/swig/python/yap.egg-info/SOURCES.txt deleted file mode 100644 index 3ee294d5d..000000000 --- a/packages/swig/python/yap.egg-info/SOURCES.txt +++ /dev/null @@ -1,14 +0,0 @@ -setup.py -yapPYTHON_wrap.cxx -/Users/vsc/github/yap-6.3/packages/python/pl2pl.c -/Users/vsc/github/yap-6.3/packages/python/pl2py.c -/Users/vsc/github/yap-6.3/packages/python/py2pl.c -/Users/vsc/github/yap-6.3/packages/python/pybips.c -/Users/vsc/github/yap-6.3/packages/python/pypreds.c -/Users/vsc/github/yap-6.3/packages/python/python.c -/Users/vsc/github/yap-6.3/packages/swig/yap.i -/Users/vsc/github/yap-6.3/packages/swig/python/yapex.py -/Users/vsc/github/yap-6.3/packages/swig/python/yap.egg-info/PKG-INFO -/Users/vsc/github/yap-6.3/packages/swig/python/yap.egg-info/SOURCES.txt -/Users/vsc/github/yap-6.3/packages/swig/python/yap.egg-info/dependency_links.txt -/Users/vsc/github/yap-6.3/packages/swig/python/yap.egg-info/top_level.txt \ No newline at end of file diff --git a/packages/swig/python/yap.egg-info/dependency_links.txt b/packages/swig/python/yap.egg-info/dependency_links.txt deleted file mode 100644 index 8b1378917..000000000 --- a/packages/swig/python/yap.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/packages/swig/python/yap.egg-info/top_level.txt b/packages/swig/python/yap.egg-info/top_level.txt deleted file mode 100644 index 20f557b10..000000000 --- a/packages/swig/python/yap.egg-info/top_level.txt +++ /dev/null @@ -1,2 +0,0 @@ -yap -yapex diff --git a/packages/python/yapi.py b/packages/swig/python/yapi.py similarity index 69% rename from packages/python/yapi.py rename to packages/swig/python/yapi.py index 5329de897..37622d095 100644 --- a/packages/python/yapi.py +++ b/packages/swig/python/yapi.py @@ -1,8 +1,22 @@ import yap +import os.path import sys # debugging support. import pdb +from collections import namedtuple + +yap_lib_path = os.path.dirname(__file__) + +use_module = namedtuple( 'use_module', 'file') +bindvars = namedtuple( 'bindvars', 'list') +library = namedtuple( 'library', 'list') +v = namedtuple( '_', 'slot') + + + +def numbervars( engine, l ): + return engine.fun(bindvars(l)) def query_prolog(engine, s): @@ -14,38 +28,39 @@ def query_prolog(engine, s): return False # - #construct a query from a one-line string + # construct a query from a one-line string # q is opaque to Python q = engine.query(s) # vs is the list of variables # you can print it out, the left-side is the variable name, # the right side wraps a handle to a variable + # pdb.set_trace() vs = q.namedVars() + #pdb.set_trace() # atom match either symbols, or if no symbol exists, sttrings, In this case # variable names should match strings - for eq in vs: - if not isinstance(eq[0],str): - print( "Error: Variable Name matches a Python Symbol") - return + #for eq in vs: + # if not isinstance(eq[0],str): + # print( "Error: Variable Name matches a Python Symbol") + # return ask = True # launch the query while answer(q): # this new vs should contain bindings to vars vs= q.namedVars() - #numbervars + print( vs ) + gs = numbervars( engine, vs) + print(gs) i=0 - # iteratw - for eq in vs: + # iterate + for eq in gs: name = eq[0] + binding = eq[1] # this is tricky, we're going to bind the variables in the term so thay we can # output X=Y. The Python way is to use dictionares. #Instead, we use the T function to tranform the Python term back to Prolog - binding = yap.T(eq[1]) - if binding.isVar(): - binding.unify(name) - else: - i = binding.numberVars(i, True) - print(name + " = " + binding.text()) + if name != binding: + print(name + " = " + str(binding)) #ok, that was Prolog code print("yes") # deterministic = one solution @@ -73,9 +88,13 @@ def query_prolog(engine, s): def live(): - engine = yap.YAPEngine() + args = yap.YAPEngineArgs() + args.setYapLibDir(yap_lib_path) + args.setYapShareDir(yap_lib_path) + #args.setYapPrologBootFile(os.path.join(yap_lib_path."startup.yss")) + engine = yap.YAPEngine( args ) + engine.goal( use_module( library('yapi') ) ) loop = True - pdb.set_trace() while loop: try: s = input("?- ") @@ -98,4 +117,4 @@ def live(): # initialize engine # engine = yap.YAPEngine(); # engine = yap.YAPEngine(yap.YAPParams()); -#live() +live() diff --git a/packages/swig/yap.i b/packages/swig/yap.i index 774dc26d4..fd6c4c5c8 100644 --- a/packages/swig/yap.i +++ b/packages/swig/yap.i @@ -29,7 +29,7 @@ class YAPEngine; extern "C" { extern X_API YAP_Term pythonToYAP(PyObject *pVal); - extern X_API PyObject * yap_to_python(YAP_Term t, bool eval); + extern X_API PyObject * yap_to_python(YAP_Term t, bool eval, PyObject *ctx); X_API extern bool init_python(void); extern X_API PyObject *py_Main; extern X_API PyObject *py_Builtin; @@ -84,13 +84,14 @@ class YAPEngine; $1 = true; } -%typemap(in) Term { $1 = pythonToYAP($input); } +%typemap(in) Term { $1 = pythonToYAP($input); PyErr_Clear(); } + +%typemap(in) YAPTerm { $1 = pythonToYAP($input); PyErr_Clear(); } -%typemap(out) YAP_Term { return $result = yap_to_python($1, false);} - -%typemap(out) Term { return $result = yap_to_python($1, false);} +%typemap(out) YAP_Term { return $result = yap_to_python($1, false, 0); } +%typemap(out) Term { return $result = yap_to_python($1, false, 0); } %extend(out) Term{Term & __getitem__(size_t i){Term t0 = $self; @@ -103,6 +104,7 @@ class YAPEngine; return HeadOfTerm(t0); else if (i == 1) return TailOfTerm(t0); + else throw( DOMAIN_ERROR_OUT_OF_RANGE, MkIntegerTerm(i), "__getitem__"); } } } @@ -126,7 +128,9 @@ class YAPEngine; case DOMAIN_ERROR: { switch (en) { case DOMAIN_ERROR_OUT_OF_RANGE: - case DOMAIN_ERROR_NOT_LESS_THAN_ZERO: + pyerr = PyExc_GeneratorExit; + break; +case DOMAIN_ERROR_NOT_LESS_THAN_ZERO: pyerr = PyExc_IndexError; break; case DOMAIN_ERROR_CLOSE_OPTION: @@ -369,3 +373,4 @@ class YAPEngine; %init %{ %} +