diff --git a/C/c_interface.c b/C/c_interface.c index a535cb95f..703271217 100755 --- a/C/c_interface.c +++ b/C/c_interface.c @@ -2509,6 +2509,14 @@ YAP_file_type_t YAP_Init(YAP_init_args *yap_init) { Yap_PutValue(AtomExtendFileSearchPath, MkAtomTerm(Yap_LookupAtom(yap_init->YapPrologAddPath))); } + if (yap_init->YapShareDir) { + setAtomicGlobalPrologFlag(PROLOG_LIBRARY_DIRECTORY_FLAG, + MkAtomTerm(Yap_LookupAtom(yap_init->YapShareDir))); + } + if (yap_init->YapLibDir) { + setAtomicGlobalPrologFlag(PROLOG_FOREIGN_DIRECTORY_FLAG, + MkAtomTerm(Yap_LookupAtom(yap_init->YapLibDir))); + } if (yap_init->QuietMode) { setVerbosity(TermSilent); } diff --git a/C/exec.c b/C/exec.c index ee150dc90..4481b3c5f 100755 --- a/C/exec.c +++ b/C/exec.c @@ -2107,12 +2107,12 @@ static Int jump_env(USES_REGS1) { Yap_find_prolog_culprit(PASS_REGS1); // LOCAL_Error_TYPE = ERROR_EVENT; - t = ArgOfTerm(1, t); - if (IsApplTerm(t) && IsAtomTerm((t2 = ArgOfTerm(1, t)))) { + Term t1 = ArgOfTerm(1, t); + if (IsApplTerm(t) && IsAtomTerm((t2 = ArgOfTerm(1, t1)))) { LOCAL_ActiveError->errorAsText = AtomOfTerm(t2); - LOCAL_ActiveError->classAsText = NameOfFunctor(FunctorOfTerm(t)); + LOCAL_ActiveError->classAsText = NameOfFunctor(FunctorOfTerm(t1)); } else if (IsAtomTerm(t)) { - LOCAL_ActiveError->errorAsText = AtomOfTerm(t); + LOCAL_ActiveError->errorAsText = AtomOfTerm(t1); LOCAL_ActiveError->classAsText = NULL; } } else { diff --git a/C/flags.c b/C/flags.c index f670bb1cf..6a2f66326 100644 --- a/C/flags.c +++ b/C/flags.c @@ -974,7 +974,7 @@ static Int current_prolog_flag2(USES_REGS1) { tarr = LOCAL_Flags; tout = tarr[fv->FlagOfVE].at; if (tout == TermZERO) { - Yap_DebugPlWriteln(tflag); + // Yap_DebugPlWriteln(tflag); return false; } if (IsVarTerm(tout)) diff --git a/C/load_dl.c b/C/load_dl.c index af5ed6f00..01da66384 100755 --- a/C/load_dl.c +++ b/C/load_dl.c @@ -162,26 +162,29 @@ int Yap_CloseForeignFile(void *handle) { static Int LoadForeign(StringList ofiles, StringList libs, char *proc_name, YapInitProc *init_proc) { CACHE_REGS + LOCAL_ErrorMessage = NULL; + while (libs) { const char *file = AtomName(libs->name); if (!Yap_findFile(file, NULL, NULL, LOCAL_FileNameBuf, true, YAP_OBJ, true, true)) { + LOCAL_ErrorMessage = malloc(MAX_ERROR_MSG_SIZE); /* use LD_LIBRARY_PATH */ - strncpy(LOCAL_FileNameBuf, (char *)AtomName(libs->name), - YAP_FILENAME_MAX); + strncpy(LOCAL_ErrorMessage, (char *)AtomName(libs->name), + YAP_FILENAME_MAX); } #ifdef __osf__ if ((libs->handle = dlopen(LOCAL_FileNameBuf, RTLD_LAZY)) == NULL) #else - if ((libs->handle = dlopen(LOCAL_FileNameBuf, RTLD_LAZY | RTLD_GLOBAL)) == - NULL) + if ((libs->handle = dlopen(LOCAL_FileNameBuf, RTLD_LAZY | RTLD_GLOBAL)) == + NULL) #endif - { - LOCAL_ErrorMessage = malloc(MAX_ERROR_MSG_SIZE); - strcpy(LOCAL_ErrorMessage, dlerror()); - return LOAD_FAILLED; - } + { + if (LOCAL_ErrorMessage == NULL) { + LOCAL_ErrorMessage = malloc(MAX_ERROR_MSG_SIZE); + strcpy(LOCAL_ErrorMessage, dlerror()); + } } libs = libs->next; } @@ -194,10 +197,11 @@ static Int LoadForeign(StringList ofiles, StringList libs, char *proc_name, /* dlopen wants to follow the LD_CONFIG_PATH */ const char *file = AtomName(ofiles->name); if (!Yap_findFile(file, NULL, NULL, LOCAL_FileNameBuf, true, YAP_OBJ, true, true)) { - LOCAL_ErrorMessage = malloc(MAX_ERROR_MSG_SIZE); - strcpy(LOCAL_ErrorMessage, - "%% Trying to open unexisting file in LoadForeign"); - return LOAD_FAILLED; + if (LOCAL_ErrorMessage == NULL) { + LOCAL_ErrorMessage = malloc(MAX_ERROR_MSG_SIZE); + strcpy(LOCAL_ErrorMessage, + "%% Trying to open unexisting file in LoadForeign"); + } } #ifdef __osf__ if ((handle = dlopen(LOCAL_FileNameBuf, RTLD_LAZY)) == 0) @@ -205,10 +209,11 @@ static Int LoadForeign(StringList ofiles, StringList libs, char *proc_name, if ((handle = dlopen(LOCAL_FileNameBuf, RTLD_LAZY | RTLD_GLOBAL)) == 0) #endif { - fprintf(stderr, "dlopen of image %s failed: %s\n", LOCAL_FileNameBuf, + if (LOCAL_ErrorMessage == NULL) { + LOCAL_ErrorMessage = malloc(MAX_ERROR_MSG_SIZE); + fprintf(stderr, "dlopen of image %s failed: %s\n", LOCAL_FileNameBuf, dlerror()); - /* strcpy(LOCAL_ErrorSay,dlerror());*/ - return LOAD_FAILLED; + } } ofiles->handle = handle; @@ -216,18 +221,15 @@ static Int LoadForeign(StringList ofiles, StringList libs, char *proc_name, if (proc_name && !*init_proc) *init_proc = (YapInitProc)dlsym(handle, proc_name); ofiles = ofiles->next; - } + } - if (!*init_proc) { - LOCAL_ErrorMessage = malloc(MAX_ERROR_MSG_SIZE); - snprintf(LOCAL_ErrorMessage, - "Could not locate routine %s in %s: %s\n", - proc_name, LOCAL_FileNameBuf, dlerror()); - fprintf(stderr, - "Could not locate routine %s in %s: %s\n", - proc_name, LOCAL_FileNameBuf, dlerror()); + if (!*init_proc && LOCAL_ErrorMessage == NULL) { + LOCAL_ErrorMessage = malloc(MAX_ERROR_MSG_SIZE); + snprintf(LOCAL_ErrorMessage,MAX_ERROR_MSG_SIZE-1, + "Could not locate routine %s in %s: %s\n", + proc_name, LOCAL_FileNameBuf, dlerror()); return LOAD_FAILLED; - } + } return LOAD_SUCCEEDED; } diff --git a/C/signals.c b/C/signals.c index b2684b519..17b6c8baa 100755 --- a/C/signals.c +++ b/C/signals.c @@ -67,7 +67,8 @@ static yap_signals InteractSIGINT(int ch) { #if PUSH_REGS // restore_absmi_regs(&Yap_standard_regs); #endif - siglongjmp(LOCAL_RestartEnv, 4); + LOCAL_RestartEnv = malloc( sizeof(sigjmp_buf) ); + siglongjmp(*LOCAL_RestartEnv, 4); return YAP_ABORT_SIGNAL; case 'b': /* continue */ diff --git a/CMakeLists.txt b/CMakeLists.txt index 726243473..ecd4ef4f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,9 @@ # value of 3.4.0 or lower. + if(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) + endif(COMMAND cmake_policy) + # Sets the version of CMake required to build the native # library. You should either keep the default value or pass a # value of 3.4.0 or lower. @@ -7,6 +11,7 @@ include(CMakeToolsHelpers OPTIONAL) project( YAP ) + if (ANDROID) set(YAP_APP_DIR "${CMAKE_SOURCE_DIR}/../..") cmake_policy(VERSION 3.4) diff --git a/CXX/yapi.cpp b/CXX/yapi.cpp index 0c7fbe08c..23836b25a 100644 --- a/CXX/yapi.cpp +++ b/CXX/yapi.cpp @@ -1,6 +1,4 @@ - - #define YAP_CPP_INTERFACE 1 #include "yapi.hh" @@ -13,21 +11,14 @@ extern "C" { #include "YapInterface.h" #include "blobs.h" -X_API extern char *Yap_TermToString(Term t, size_t *length, encoding_t encodingp, +X_API char *Yap_TermToString(Term t, size_t *length, encoding_t encodingp, int flags); -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, +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 extern void YAP_UserBackCPredicate(const char *, YAP_UserCPred, YAP_UserCPred, +X_API 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) @@ -384,6 +375,7 @@ Term YAPListTerm::car() { Yap_Error(TYPE_ERROR_LIST, to, ""); throw YAPError(); + return 0; } } @@ -554,11 +546,6 @@ void YAPEngine::release() RECOVER_MACHINE_REGS(); } -YAPTerm YAPEngine::fun(YAPTerm t) -{ - return YAPTerm(fun(t.term())); -} - Term YAPEngine::fun(Term t) { CACHE_REGS @@ -572,11 +559,6 @@ Term YAPEngine::fun(Term t) sigjmp_buf q_env; 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; @@ -631,7 +613,6 @@ Term YAPEngine::fun(Term t) Yap_CloseHandles(q.CurSlot); RECOVER_MACHINE_REGS(); return XREGS[arity]; - Yap_DebugPlWriteln(XREGS[arity]); } catch (YAPError e) { @@ -676,7 +657,7 @@ YAPQuery::YAPQuery(YAPPredicate p, YAPTerm ts[]) : YAPPredicate(p.ap) bool YAPQuery::next() { CACHE_REGS - bool result; + bool result = false; Term terr; LOCAL_RestartEnv = &q_env; try @@ -791,8 +772,6 @@ void YAPQuery::close() RECOVER_MACHINE_REGS(); } -static YAPEngine *curren; - #if __ANDROID__ #include @@ -849,19 +828,9 @@ 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(&engine_args.init_args)) == YAP_FOUND_BOOT_ERROR) + if ((BootMode = YAP_Init(&engine_args->init_args)) == YAP_FOUND_BOOT_ERROR) { throw YAPError(); } @@ -875,9 +844,6 @@ 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()) { @@ -889,38 +855,20 @@ void YAPEngine::doInit(YAP_file_type_t BootMode) } } -YAPEngine::YAPEngine(YAPEngineArgs &argp) - : _callback(0) -{ // a single engine can be active - - engine_args = argp; - YAP_file_type_t BootMode; - __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "YAP %s ", bootFile); - - // delYAPCallback()b - // if (cb) - // setYAPCallback(cb); - curren = this; - BootMode = engine_args.init_args.boot_file_type; - doInit(BootMode); - -} - YAPEngine::YAPEngine(int argc, char *argv[], YAPCallback *cb) - : _callback(0) -{ // a single engine can be active + : _callback(0) { // a single engine can be active - engine_args = YAPEngineArgs(); YAP_file_type_t BootMode; - BootMode = YAP_parse_yap_arguments(argc, argv, &engine_args.init_args); + engine_args = new YAPEngineArgs(); + BootMode = YAP_parse_yap_arguments(argc, argv, &engine_args->init_args); // delYAPCallback()b // if (cb) // setYAPCallback(cb); - curren = this; doInit(BootMode); } + YAPPredicate::YAPPredicate(YAPAtom at) { CACHE_REGS diff --git a/CXX/yapi.hh b/CXX/yapi.hh index a4b840ef8..6a458aa72 100644 --- a/CXX/yapi.hh +++ b/CXX/yapi.hh @@ -76,16 +76,21 @@ extern "C" { // taken from yap_structs.h #include "iopreds.h" - X_API void YAP_UserCPredicate(const char *, YAP_UserCPred, YAP_Arity arity); + X_API extern void YAP_UserCPredicate(const char *, YAP_UserCPred, YAP_Arity arity); - /* void UserCPredicateWithArgs(const char *name, int *fn(), unsigned int arity) + /* extern void UserCPredicateWithArgs(const char *name, int *fn(), unsigned int arity) */ - X_API void YAP_UserCPredicateWithArgs(const char *, YAP_UserCPred, YAP_Arity, - YAP_Term); + X_API extern void YAP_UserCPredicateWithArgs(const char *, YAP_UserCPred, YAP_Arity, + YAP_Term); - X_API void UserBackCPredicate(const char *name, int *init(), int *cont(), int - arity, int extra); + X_API extern void UserBackCPredicate(const char *name, int *init(), int *cont(), int + arity, int extra); +#if YAP_PYTHON +#include + + extern bool python_in_python; +#endif } class YAPEngine; diff --git a/CXX/yapq.hh b/CXX/yapq.hh index 6e69167a3..3b431383c 100644 --- a/CXX/yapq.hh +++ b/CXX/yapq.hh @@ -147,19 +147,13 @@ public: }; - class YAPEngine; - /// @brief Setup all arguments to a new engine class YAPEngineArgs { - friend class YAPEngine; - - YAP_init_args init_args; - - void fetch_defaults(); - public: + YAP_init_args init_args; + inline void setEmbedded( bool fl ) { init_args.Embedded = fl; @@ -217,7 +211,8 @@ public: inline void setYapLibDir( const char * fl ) { - init_args.YapLibDir = fl; + init_args.YapLibDir = (const char *)malloc(strlen(fl)+1); + strcpy((char *)init_args.YapLibDir, fl); }; inline const char * getYapLibDir( ) @@ -227,7 +222,8 @@ public: inline void setYapShareDir( const char * fl ) { - init_args.YapShareDir = fl; + init_args.YapShareDir = (const char *)malloc(strlen(fl)+1); + strcpy((char *)init_args.YapShareDir, fl); }; inline const char * getYapShareDir( ) @@ -237,8 +233,9 @@ public: inline void setYapPrologBootFile( const char * fl ) { - init_args.YapPrologBootFile = fl; - }; + init_args.YapPrologBootFile = (const char *)malloc(strlen(fl)+1); + strcpy((char *)init_args.YapPrologBootFile, fl); +}; inline const char * getYapPrologBootFile( ) { @@ -305,23 +302,26 @@ public: return init_args.Argv; }; - - YAPEngineArgs() { - fetch_defaults(); - }; - + YAPEngineArgs() { + Yap_InitDefaults(&init_args, NULL, 0, NULL); +#if YAP_PYTHON + init_args.Embedded = true; + python_in_python = Py_IsInitialized(); +#endif + }; }; + /** * @brief YAP Engine: takes care of the execution environment where we can go executing goals. * * */ -class YAPEngine + class YAPEngine { private: - YAPEngineArgs engine_args; + YAPEngineArgs *engine_args; YAPCallback *_callback; YAPError yerror; void doInit(YAP_file_type_t BootMode); @@ -329,20 +329,24 @@ private: public: /// construct a new engine; may use a variable number of arguments - YAPEngine(YAPEngineArgs &cargs); /// construct a new engine, including aaccess to callbacks - /// construct a new engine using argc/argv list of arguments + YAPEngine(YAPEngineArgs *cargs) { + engine_args = cargs; + //doInit(cargs->init_args.boot_file_type); + doInit(YAP_QLY); + }; /// 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); + YAPCallback *callback = (YAPCallback *)NULL); /// kill engine - ~YAPEngine() { delYAPCallback(); } + ~YAPEngine() { delYAPCallback(); }; /// remove current callback - void delYAPCallback() { _callback = 0; } + void delYAPCallback() { _callback = 0; }; /// set a new callback void setYAPCallback(YAPCallback *cb) { delYAPCallback(); _callback = cb; - } + }; /// execute the callback. ////void run() { if (_callback) _callback.run(); } /// execute the callback with a text argument. @@ -395,8 +399,14 @@ public: //> 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); + YAPTerm fun(YAPTerm t) { return YAPTerm(fun(t.term())); }; Term fun(Term t); + //> set a StringFlag, usually a path + //> + bool setStringFlag(std::string arg, std::string path) + { + return setYapFlag(MkAtomTerm(Yap_LookupAtom(arg.data())), MkAtomTerm(Yap_LookupAtom(path.data()))); + }; }; #endif /* YAPQ_HH */ diff --git a/CXX/yapt.hh b/CXX/yapt.hh index f950b5814..d6e754838 100644 --- a/CXX/yapt.hh +++ b/CXX/yapt.hh @@ -194,7 +194,8 @@ public: Term t0 = gt(); if (IsApplTerm(t0)) { - if (i > t) YAPError(DOMAIN_ERROR_OUT_OF_RANGE, t0, "t0.getArg()"); + if (i > ArityOfFunctor(FunctorOfTerm(t0))) + YAPError(DOMAIN_ERROR_OUT_OF_RANGE, t0, "t0.getArg()"); tf = (ArgOfTerm(i, t0)); } else if (IsPairTerm(t0)) { if (i == 1) diff --git a/H/YapGFlagInfo.h b/H/YapGFlagInfo.h index e38c65af8..6dc47f309 100644 --- a/H/YapGFlagInfo.h +++ b/H/YapGFlagInfo.h @@ -283,117 +283,121 @@ style checking, handling calls to undefined procedures, how directives are interpreted, when to use dynamic, character escapes, and how files are consulted. Also check the `dialect` option. */ - YAP_FLAG(MAX_ARITY_FLAG, "max_arity", false, isatom, "unbounded", - NULL), /**< `max_arity is iso ` + YAP_FLAG(PROLOG_LIBRARY_DIRECTORY_FLAG, "prolog_library_directory", true, isatom, "", NULL), /**< if defined, first location where YAP expects to find the YAP Prolog library. Takes precedence over library_directory */ + + YAP_FLAG(PROLOG_FOREIGN_DIRECTORY_FLAG, "prolog_foreign_directory", true, isatom, "", NULL), /**< if defined, first location where YAP expects to find the YAP Prolog shared libraries (DLLS). Takes precedence over executable_directory/2. */ + + YAP_FLAG(MAX_ARITY_FLAG, "max_arity", false, isatom, "unbounded", + NULL), /**< `max_arity is iso ` Read-only flag telling the maximum arity of a functor. Takes the value `unbounded` for the current version of YAP. -*/ - YAP_FLAG(MAX_TAGGED_INTEGER_FLAG, "max_tagged_integer", false, at2n, - "INT_MAX", NULL), - YAP_FLAG(MAX_THREADS_FLAG, "max_threads", false, at2n, "MAX_THREADS", NULL), - YAP_FLAG(MAX_WORKERS_FLAG, "max_workers", false, at2n, "MAX_WORKERS", NULL), - YAP_FLAG(MIN_TAGGED_INTEGER_FLAG, "min_tagged_integer", false, at2n, - "INT_MIN", NULL), - YAP_FLAG(N_OF_INTEGER_KEYS_IN_DB_FLAG, "n_of_integer_keys_in_db", false, ro, - "256", NULL), - YAP_FLAG(OCCURS_CHECK_FLAG, "occurs_check", true, booleanFlag, "false", - NULL), - YAP_FLAG(OPEN_EXPANDS_FILENAME_FLAG, "open_expands_filename", true, - booleanFlag, "false", NULL), /**< `open_expands_filename ` + */ + YAP_FLAG(MAX_TAGGED_INTEGER_FLAG, "max_tagged_integer", false, at2n, + "INT_MAX", NULL), + YAP_FLAG(MAX_THREADS_FLAG, "max_threads", false, at2n, "MAX_THREADS", NULL), + YAP_FLAG(MAX_WORKERS_FLAG, "max_workers", false, at2n, "MAX_WORKERS", NULL), + YAP_FLAG(MIN_TAGGED_INTEGER_FLAG, "min_tagged_integer", false, at2n, + "INT_MIN", NULL), + YAP_FLAG(N_OF_INTEGER_KEYS_IN_DB_FLAG, "n_of_integer_keys_in_db", false, ro, + "256", NULL), + YAP_FLAG(OCCURS_CHECK_FLAG, "occurs_check", true, booleanFlag, "false", + NULL), + YAP_FLAG(OPEN_EXPANDS_FILENAME_FLAG, "open_expands_filename", true, + booleanFlag, "false", NULL), /**< `open_expands_filename ` - If `true` the open/3 builtin performs filename-expansion - before opening a file (SICStus Prolog like). If `false` it does not - (SWI-Prolog like). - */ - YAP_FLAG(OPEN_SHARED_OBJECT_FLAG, "open_shared_object", true, booleanFlag, - "true", NULL), /**< `open_shared_object ` +If `true` the open/3 builtin performs filename-expansion +before opening a file (SICStus Prolog like). If `false` it does not +(SWI-Prolog like). + */ + YAP_FLAG(OPEN_SHARED_OBJECT_FLAG, "open_shared_object", true, booleanFlag, + "true", NULL), /**< `open_shared_object ` If true, `open_shared_object/2` and friends are implemented, providing access to shared libraries (`.so` files) or to dynamic link libraries (`.DLL` files). -*/ - // YAP_FLAG(MODULE_INDEPENDENT_OPERATORS_FLAG, - // "module_independent_operators", true, booleanFlag, - // "false", NULL), - /**< `module_independent_operators ` + */ + // YAP_FLAG(MODULE_INDEPENDENT_OPERATORS_FLAG, + // "module_independent_operators", true, booleanFlag, + // "false", NULL), + /**< `module_independent_operators ` - If `true` an operator declaration will be valid for every module in the - program. This is for compatibility with old software that - might expect module-independent operators. - */ - YAP_FLAG(OPTIMISE_FLAG, "optimise", true, booleanFlag, "false", NULL), - YAP_FLAG(OS_ARGV_FLAG, "os_argv", false, os_argv, "@boot", NULL), - YAP_FLAG(PID_FLAG, "pid", false, sys_pid, "@boot", NULL), - YAP_FLAG(PIPE_FLAG, "pipe", true, booleanFlag, "true", NULL), - YAP_FLAG(PROFILING_FLAG, "profiling", true, booleanFlag, "false", - NULL), /**< `profiling ` + If `true` an operator declaration will be valid for every module in the + program. This is for compatibility with old software that + might expect module-independent operators. + */ + YAP_FLAG(OPTIMISE_FLAG, "optimise", true, booleanFlag, "false", NULL), + YAP_FLAG(OS_ARGV_FLAG, "os_argv", false, os_argv, "@boot", NULL), + YAP_FLAG(PID_FLAG, "pid", false, sys_pid, "@boot", NULL), + YAP_FLAG(PIPE_FLAG, "pipe", true, booleanFlag, "true", NULL), + YAP_FLAG(PROFILING_FLAG, "profiling", true, booleanFlag, "false", + NULL), /**< `profiling ` If `off` (default) do not compile call counting information for procedures. If `on` compile predicates so that they calls and retries to the predicate may be counted. Profiling data can be read through the call_count_data/3 built-in. -*/ - YAP_FLAG(PROMPT_ALTERNATIVES_ON_FLAG, "prompt_alternatives_on", true, - isatom, "determinism", NULL), /**< `prompt_alternatives_on(atom, -changeable) ` + */ + YAP_FLAG(PROMPT_ALTERNATIVES_ON_FLAG, "prompt_alternatives_on", true, + isatom, "determinism", NULL), /**< `prompt_alternatives_on(atom, + changeable) ` -SWI-Compatible option, determines prompting for alternatives in the Prolog -toplevel. Default is groundness, YAP prompts for alternatives if and -only if the query contains variables. The alternative, default in SWI-Prolog is -determinism which implies the system prompts for alternatives if the -goal succeeded while leaving choicepoints. */ - YAP_FLAG(QUASI_QUOTATIONS_FLAG, "quasi_quotations", true, booleanFlag, - "true", NULL), - YAP_FLAG(READLINE_FLAG, "readline", true, booleanFlag, "false", - Yap_InitReadline), /**< `readline(boolean, changeable)` -} + SWI-Compatible option, determines prompting for alternatives in the Prolog + toplevel. Default is groundness, YAP prompts for alternatives if and + only if the query contains variables. The alternative, default in SWI-Prolog is + determinism which implies the system prompts for alternatives if the + goal succeeded while leaving choicepoints. */ + YAP_FLAG(QUASI_QUOTATIONS_FLAG, "quasi_quotations", true, booleanFlag, + "true", NULL), + YAP_FLAG(READLINE_FLAG, "readline", true, booleanFlag, "false", + Yap_InitReadline), /**< `readline(boolean, changeable)` + } -enable the use of the readline library for console interactions, true by default -if readline was found. */ - YAP_FLAG(REPORT_ERROR_FLAG, "report_error", true, booleanFlag, "true", - NULL), - YAP_FLAG(RESOURCE_DATABASE_FLAG, "resource_database", false, isatom, - "boot.yap", NULL), - /**<`resource_database` - Name of the resource file (saved-state or Prolog file) used to construct - the YAP - run-time environment. - */ - YAP_FLAG(SAVED_PROGRAM_FLAG, "saved_program", false, booleanFlag, "false", - NULL), - /**<`saved_program` - if `true` YAP booted from a `yss` file, usually `startup.yss'. If - `false`, YAP booted from a Prolog file, by default `boot.yap`. - */ - YAP_FLAG(SHARED_OBJECT_EXTENSION_FLAG, "shared_object_extension", false, - isatom, SO_EXT, NULL), /**< `shared_object_extension ` + enable the use of the readline library for console interactions, true by default + if readline was found. */ + YAP_FLAG(REPORT_ERROR_FLAG, "report_error", true, booleanFlag, "true", + NULL), + YAP_FLAG(RESOURCE_DATABASE_FLAG, "resource_database", false, isatom, + "boot.yap", NULL), + /**<`resource_database` + Name of the resource file (saved-state or Prolog file) used to construct + the YAP + run-time environment. + */ + YAP_FLAG(SAVED_PROGRAM_FLAG, "saved_program", false, booleanFlag, "false", + NULL), + /**<`saved_program` + if `true` YAP booted from a `yss` file, usually `startup.yss'. If + `false`, YAP booted from a Prolog file, by default `boot.yap`. + */ + YAP_FLAG(SHARED_OBJECT_EXTENSION_FLAG, "shared_object_extension", false, + isatom, SO_EXT, NULL), /**< `shared_object_extension ` Suffix associated with loadable code. -*/ - YAP_FLAG(SHARED_OBJECT_SEARCH_PATH_FLAG, "shared_object_search_path", true, - isatom, SO_PATH, NULL), /**< `shared_object_search_path ` + */ + YAP_FLAG(SHARED_OBJECT_SEARCH_PATH_FLAG, "shared_object_search_path", true, + isatom, SO_PATH, NULL), /**< `shared_object_search_path ` Name of the environment variable used by the system to search for shared objects. -*/ - YAP_FLAG(SIGNALS_FLAG, "signals", true, booleanFlag, "true", - NULL), /**< `signals` + */ + YAP_FLAG(SIGNALS_FLAG, "signals", true, booleanFlag, "true", + NULL), /**< `signals` - If `true` (default) YAP handles Signals such as `^C` - (`SIGINT`). +If `true` (default) YAP handles Signals such as `^C` +(`SIGINT`). - */ - YAP_FLAG(SOURCE_FLAG, "source", true, booleanFlag, "true", - NULL), /**< `source` + */ + YAP_FLAG(SOURCE_FLAG, "source", true, booleanFlag, "true", + NULL), /**< `source` If `true` maintain the source for all clauses. Notice that this is trivially supported for facts, and always supported for dynamic code. -*/ - YAP_FLAG(STRICT_ISO_FLAG, "strict_iso", true, booleanFlag, "false", - NULL), /**< `strict_iso ` + */ + YAP_FLAG(STRICT_ISO_FLAG, "strict_iso", true, booleanFlag, "false", + NULL), /**< `strict_iso ` If _Value_ is unbound, tell whether strict ISO compatibility mode is `on` or `off`. If _Value_ is bound to `on` set @@ -414,51 +418,51 @@ will work the same way in every Prolog and in every platform. We thus believe this mode is mostly useful when investigating how a program depends on a Prolog's platform specific features. - */ - YAP_FLAG(SYSTEM_OPTIONS_FLAG, "system_options", false, options, - SYSTEM_OPTIONS, - NULL), /**< `system_options ` + */ + YAP_FLAG(SYSTEM_OPTIONS_FLAG, "system_options", false, options, + SYSTEM_OPTIONS, + NULL), /**< `system_options ` This read only flag tells which options were used to compile YAP. Currently it informs whether the system supports `big_numbers`, `coroutining`, `depth_limit`, `low_level_tracer`, `or-parallelism`, `rational_trees`, `readline`, `tabling`, `threads`, or the `wam_profiler`. -*/ - YAP_FLAG(SYSTEM_THREAD_ID_FLAG, "system_thread_id", false, sys_thread_id, - "@boot", NULL), - YAP_FLAG(TABLING_MODE_FLAG, "tabling_mode", true, isatom, "[]", - NULL), /**< `tabling_mode` + */ + YAP_FLAG(SYSTEM_THREAD_ID_FLAG, "system_thread_id", false, sys_thread_id, + "@boot", NULL), + YAP_FLAG(TABLING_MODE_FLAG, "tabling_mode", true, isatom, "[]", + NULL), /**< `tabling_mode` Sets or reads the tabling mode for all tabled predicates. Please (see Tabling) for the list of options. -*/ - YAP_FLAG(THREADS_FLAG, "threads", false, ro, "MAX_THREADS", NULL), - YAP_FLAG(TIMEZONE_FLAG, "timezone", false, ro, "18000", NULL), - YAP_FLAG(TOPLEVEL_PRINT_ANON_FLAG, "toplevel_print_anon", true, booleanFlag, - "true", NULL), - YAP_FLAG(TOPLEVEL_PRINT_OPTIONS_FLAG, "toplevel_print_options", true, - list_option, "[quoted(true),numbervars(true),portrayed(true)]", - NULL), /**< `toplevel_hook ` + */ + YAP_FLAG(THREADS_FLAG, "threads", false, ro, "MAX_THREADS", NULL), + YAP_FLAG(TIMEZONE_FLAG, "timezone", false, ro, "18000", NULL), + YAP_FLAG(TOPLEVEL_PRINT_ANON_FLAG, "toplevel_print_anon", true, booleanFlag, + "true", NULL), + YAP_FLAG(TOPLEVEL_PRINT_OPTIONS_FLAG, "toplevel_print_options", true, + list_option, "[quoted(true),numbervars(true),portrayed(true)]", + NULL), /**< `toplevel_hook ` If bound, set the argument to a goal to be executed before entering the top-level. If unbound show the current goal or `true` if none is presented. Only the first solution is considered and the goal is not backtracked into. -*/ - YAP_FLAG(TOPLEVEL_PROMPT_FLAG, "toplevel_prompt", true, isatom, "?- ", - mkprompt), - YAP_FLAG(TTY_CONTROL_FLAG, "tty_control", true, booleanFlag, "true", NULL), - YAP_FLAG(UNIX_FLAG, "unix", false, ro, "true", NULL), /**< `unix` + */ + YAP_FLAG(TOPLEVEL_PROMPT_FLAG, "toplevel_prompt", true, isatom, "?- ", + mkprompt), + YAP_FLAG(TTY_CONTROL_FLAG, "tty_control", true, booleanFlag, "true", NULL), + YAP_FLAG(UNIX_FLAG, "unix", false, ro, "true", NULL), /**< `unix` - Read-only BooleanFlag flag that unifies with `true` if YAP is +Read-only BooleanFlag flag that unifies with `true` if YAP is running on an Unix system. Defined if the C-compiler used to compile this version of YAP either defines `__unix__` or `unix`. - */ - YAP_FLAG(UPDATE_SEMANTICS_FLAG, "update_semantics", true, isatom, "logical", - NULL), /**< `update_semantics ` + */ + YAP_FLAG(UPDATE_SEMANTICS_FLAG, "update_semantics", true, isatom, "logical", + NULL), /**< `update_semantics ` Define whether YAP should follow `immediate` update semantics, as in C-Prolog (default), `logical` update semantics, @@ -466,93 +470,93 @@ as in Quintus Prolog, SICStus Prolog, or in the ISO standard. There is also an intermediate mode, `logical_assert`, where dynamic procedures follow logical semantics but the internal data base still follows immediate semantics. -*/ - YAP_FLAG(USER_FLAGS_FLAG, "user_flags", true, isatom, "error", NULL), /**< - `user_flags ` + */ + YAP_FLAG(USER_FLAGS_FLAG, "user_flags", true, isatom, "error", NULL), /**< + `user_flags ` - Define the behaviour of set_prolog_flag/2 if the flag is not known. Values - are `silent`, `warning` and `error`. The first two create the flag - on-the-fly, with `warning` printing a message. The value `error` is - consistent with ISO: it raises an existence error and does not create the - flag. See also `create_prolog_flag/3`. The default is`error`, and developers - are encouraged to use `create_prolog_flag/3` to create flags for their - library. - */ - YAP_FLAG(UNKNOWN_FLAG, "unknown", true, isatom, "error", - Yap_unknown), /**< `unknown is iso` + Define the behaviour of set_prolog_flag/2 if the flag is not known. Values + are `silent`, `warning` and `error`. The first two create the flag + on-the-fly, with `warning` printing a message. The value `error` is + consistent with ISO: it raises an existence error and does not create the + flag. See also `create_prolog_flag/3`. The default is`error`, and developers + are encouraged to use `create_prolog_flag/3` to create flags for their + library. + */ + YAP_FLAG(UNKNOWN_FLAG, "unknown", true, isatom, "error", + Yap_unknown), /**< `unknown is iso` Corresponds to calling the unknown/2 built-in. Possible ISO values are `error`, `fail`, and `warning`. Yap includes the following extensions: `fast_fail` does not invoke any handler. -*/ - YAP_FLAG(VARIABLE_NAMES_MAY_END_WITH_QUOTES_FLAG, - "variable_names_may_end_with_quotes", true, booleanFlag, "false", - NULL), - YAP_FLAG(VERBOSE_FLAG, "verbose", true, isatom, "normal", - NULL), /**< `verbose ` + */ + YAP_FLAG(VARIABLE_NAMES_MAY_END_WITH_QUOTES_FLAG, + "variable_names_may_end_with_quotes", true, booleanFlag, "false", + NULL), + YAP_FLAG(VERBOSE_FLAG, "verbose", true, isatom, "normal", + NULL), /**< `verbose ` If `normal` allow printing of informational and banner messages, such as the ones that are printed when consulting. If `silent` disable printing these messages. It is `normal` by default except if YAP is booted with the `-q` or `-L` flag. -*/ - YAP_FLAG(VERBOSE_AUTOLOAD_FLAG, "verbose_autoload", true, booleanFlag, - "false", NULL), - YAP_FLAG(VERBOSE_FILE_SEARCH_FLAG, "verbose_file_search", true, booleanFlag, - "false", NULL), /**< `verbose_file_search ` + */ + YAP_FLAG(VERBOSE_AUTOLOAD_FLAG, "verbose_autoload", true, booleanFlag, + "false", NULL), + YAP_FLAG(VERBOSE_FILE_SEARCH_FLAG, "verbose_file_search", true, booleanFlag, + "false", NULL), /**< `verbose_file_search ` If `true` allow printing of informational messages when searching for file names. If `false` disable printing these messages. It is `false` by default except if YAP is booted with the `-L` flag. -*/ - YAP_FLAG(VERBOSE_LOAD_FLAG, "verbose_load", true, isatom, "normal", - NULL), /**< `verbose_load ` + */ + YAP_FLAG(VERBOSE_LOAD_FLAG, "verbose_load", true, isatom, "normal", + NULL), /**< `verbose_load ` If `true` allow printing of informational messages when consulting files. If `false` disable printing these messages. It is `normal` by default except if YAP is booted with the `-L` flag. -*/ - YAP_FLAG(VERSION_FLAG, "version", false, nat, YAP_NUMERIC_VERSION, - NULL), /**< `version_data ` + */ + YAP_FLAG(VERSION_FLAG, "version", false, nat, YAP_NUMERIC_VERSION, + NULL), /**< `version_data ` Read-only flag that unifies with a number of the form `_Major_ * 100000 + _Minor_ *100 + _Patch_`, where _Major_ is the major version, _Minor_ is the minor version, and _Patch_ is the patch number. -*/ - YAP_FLAG(VERSION_DATA_FLAG, "version_data", false, ro, YAP_TVERSION, - NULL), /**< -`version ` Read-only flag that returns a compound term with the -current version of YAP. The term will have the name `yap` and arity 4, the first -argument will be the -major version, the second the minor version, the third the patch number, and the -last one is reserved. + */ + YAP_FLAG(VERSION_DATA_FLAG, "version_data", false, ro, YAP_TVERSION, + NULL), /**< + `version ` Read-only flag that returns a compound term with the + current version of YAP. The term will have the name `yap` and arity 4, the first + argument will be the + major version, the second the minor version, the third the patch number, and the + last one is reserved. -*/ - YAP_FLAG(VERSION_GIT_FLAG, "version_git", false, isatom, YAP_GIT_HEAD, - NULL), /**< `version_git ` -` -this is the unique identifier for the last commit of the current GIT HEAD, it -xan be used to identify versions that differ on small (or large) updates. - */ - YAP_FLAG(WRITE_ATTRIBUTES_FLAG, "write_attributes", true, isatom, "ignore", - NULL), + */ + YAP_FLAG(VERSION_GIT_FLAG, "version_git", false, isatom, YAP_GIT_HEAD, + NULL), /**< `version_git ` + ` + this is the unique identifier for the last commit of the current GIT HEAD, it + xan be used to identify versions that differ on small (or large) updates. + */ + YAP_FLAG(WRITE_ATTRIBUTES_FLAG, "write_attributes", true, isatom, "ignore", + NULL), #if __WINDOWS__ - YAP_FLAG(WINDOWS_FLAG, "windows", false, ro, "true", NULL), /**< `windows ` + YAP_FLAG(WINDOWS_FLAG, "windows", false, ro, "true", NULL), /**< `windows ` - Read-only booleanFlag flag that unifies with `true` if YAP is +Read-only booleanFlag flag that unifies with `true` if YAP is running on an Windows machine. - */ + */ #endif - YAP_FLAG(WRITE_STRINGS_FLAG, "write_strings", true, booleanFlag, "false", - NULL), /**< `write_strings ` + YAP_FLAG(WRITE_STRINGS_FLAG, "write_strings", true, booleanFlag, "false", + NULL), /**< `write_strings ` Writable flag telling whether the system should write lists of integers that are writable character codes using the list notation. It is `on` if enables or `off` if disabled. The default value for this flag is `off`. -*/ -//! @} + */ + //! @} diff --git a/H/Yatom.h b/H/Yatom.h index d5f5d9018..9967e9998 100755 --- a/H/Yatom.h +++ b/H/Yatom.h @@ -106,73 +106,73 @@ INLINE_ONLY inline EXTERN Prop AbsFunctorProp(FunctorEntry *p) { #endif -INLINE_ONLY inline EXTERN Int ArityOfFunctor(Functor); + INLINE_ONLY inline EXTERN arity_t ArityOfFunctor(Functor); -INLINE_ONLY inline EXTERN Int ArityOfFunctor(Functor Fun) { - return (Int)(((FunctorEntry *)Fun)->ArityOfFE); -} + INLINE_ONLY inline EXTERN arity_t ArityOfFunctor(Functor Fun) { + return (arity_t)(((FunctorEntry *)Fun)->ArityOfFE); + } -INLINE_ONLY inline EXTERN Atom NameOfFunctor(Functor); + INLINE_ONLY inline EXTERN Atom NameOfFunctor(Functor); -INLINE_ONLY inline EXTERN Atom NameOfFunctor(Functor Fun) { - return (Atom)(((FunctorEntry *)Fun)->NameOfFE); -} + INLINE_ONLY inline EXTERN Atom NameOfFunctor(Functor Fun) { + return (Atom)(((FunctorEntry *)Fun)->NameOfFE); + } -INLINE_ONLY inline EXTERN PropFlags IsFunctorProperty(int); + INLINE_ONLY inline EXTERN PropFlags IsFunctorProperty(int); -INLINE_ONLY inline EXTERN PropFlags IsFunctorProperty(int flags) { - return (PropFlags)((flags == FunctorProperty)); -} + INLINE_ONLY inline EXTERN PropFlags IsFunctorProperty(int flags) { + return (PropFlags)((flags == FunctorProperty)); + } -/* summary of property codes used + /* summary of property codes used - 00 00 predicate entry - 80 00 db property - bb 00 functor entry - ff df sparse functor - ff ex arithmetic property - ff f4 translation - ff f5 blob - ff f6 hold - ff f7 array - ff f8 wide atom - ff fa module property - ff fb blackboard property - ff fc value property - ff fd global property - ff fe flag property - ff ff op property -*/ + 00 00 predicate entry + 80 00 db property + bb 00 functor entry + ff df sparse functor + ff ex arithmetic property + ff f4 translation + ff f5 blob + ff f6 hold + ff f7 array + ff f8 wide atom + ff fa module property + ff fb blackboard property + ff fc value property + ff fd global property + ff fe flag property + ff ff op property + */ -/* Global Variable property */ -typedef struct global_entry { - Prop NextOfPE; /* used to chain properties */ - PropFlags KindOfPE; /* kind of property */ + /* Global Variable property */ + typedef struct global_entry { + Prop NextOfPE; /* used to chain properties */ + PropFlags KindOfPE; /* kind of property */ #if defined(YAPOR) || defined(THREADS) - rwlock_t GRWLock; /* a simple lock to protect this entry */ + rwlock_t GRWLock; /* a simple lock to protect this entry */ #if THREADS - unsigned int owner_id; /* owner thread */ + unsigned int owner_id; /* owner thread */ #endif #endif - struct AtomEntryStruct *AtomOfGE; /* parent atom for deletion */ - struct global_entry *NextGE; /* linked list of global entries */ - Term global; /* index in module table */ - Term AttChain; /* index in module table */ -} GlobalEntry; + struct AtomEntryStruct *AtomOfGE; /* parent atom for deletion */ + struct global_entry *NextGE; /* linked list of global entries */ + Term global; /* index in module table */ + Term AttChain; /* index in module table */ + } GlobalEntry; #if USE_OFFSETS_IN_PROPS -INLINE_ONLY inline EXTERN GlobalEntry *RepGlobalProp(Prop p); + INLINE_ONLY inline EXTERN GlobalEntry *RepGlobalProp(Prop p); -INLINE_ONLY inline EXTERN GlobalEntry *RepGlobalProp(Prop p) { - return (GlobalEntry *)(AtomBase + Unsigned(p)); -} + INLINE_ONLY inline EXTERN GlobalEntry *RepGlobalProp(Prop p) { + return (GlobalEntry *)(AtomBase + Unsigned(p)); + } -INLINE_ONLY inline EXTERN Prop AbsGlobalProp(GlobalEntry *p); + INLINE_ONLY inline EXTERN Prop AbsGlobalProp(GlobalEntry *p); -INLINE_ONLY inline EXTERN Prop AbsGlobalProp(GlobalEntry *p) { - return (Prop)(Addr(p) - AtomBase); -} + INLINE_ONLY inline EXTERN Prop AbsGlobalProp(GlobalEntry *p) { + return (Prop)(Addr(p) - AtomBase); + } #else diff --git a/Packages.cmake b/Packages.cmake index 76096a280..947530d00 100644 --- a/Packages.cmake +++ b/Packages.cmake @@ -1,21 +1,43 @@ +macro_log_feature (PYTHONLIBS_FOUND "Python" + "Use Python System" + "http://www.python.org" FALSE ) + message(STATUS "Building YAP packages version ${YAP_VERSION}") - - if (NOT WIN32) -set (BUILD_SHARED_LIBS ON) + set (BUILD_SHARED_LIBS ON) endif() option (WITH_JIT -"just in Time Clause Compilation" OFF) + "just in Time Clause Compilation" OFF) if (WITH_JIT) add_subDIRECTORY(JIT) endif (WITH_JIT) +OPTION (WITH_SWIG " Enable SWIG interfaces to foreign languages" ON) + +IF (WITH_SWIG) + find_host_package (SWIG) + macro_log_feature (SWIG_FOUND "Swig" + "Use SWIG Interface Generator " + "http://www.swig.org" ON) +ENDIF (WITH_SWIG) + +option (WITH_PYTHON + "Allow Python->YAP and YAP->Python" ON) + +IF (WITH_PYTHON) + include(python) +ENDIF (WITH_PYTHON) + + +IF (SWIG_FOUND) + add_subDIRECTORY (packages/swig) +ENDIF(SWIG_FOUND) add_subDIRECTORY (packages/raptor) @@ -29,31 +51,21 @@ OPTION (WITH_CPLINT " Enable the cplint probabilistic language" ON) OPTION (WITH_HORUS " Enable the CLPBN and PFL probabilistic languages" ON) IF (WITH_CLPBN) -add_subDIRECTORY (packages/CLPBN) + add_subDIRECTORY (packages/CLPBN) ENDIF(WITH_CLPBN) IF (WITH_CPLINT) -add_subDIRECTORY (packages/cplint) -ENDIF(WITH_CPLINT) + add_subDIRECTORY (packages/cplint) + ENDIF(WITH_CPLINT) - -#must be last -add_subDIRECTORY (packages/python) - -OPTION (WITH_SWIG " Enable SWIG interfaces to foreign languages" ON) -IF (WITH_SWIG) -add_subDIRECTORY (packages/swig) -ENDIF (WITH_SWIG) - - -# please install doxygen for prolog first -# git clone http://www.github.com/vscosta/doxygen-yap -# cd doxygen-yap -# mkdir -p build -# cd build -# make; sudo make install -option (WITH_DOCS - "generate YAP docs" OFF) + # please install doxygen for prolog first + # git clone http://www.github.com/vscosta/doxygen-yap + # cd doxygen-yap + # mkdir -p build + # cd build + # make; sudo make install + option (WITH_DOCS + "generate YAP docs" OFF) IF (WITH_DOCS) add_subDIRECTORY (docs) @@ -150,7 +162,7 @@ if(WIN32) endif(WIN32) - add_executable (yap-bin ${CONSOLE_SOURCES}) +add_executable (yap-bin ${CONSOLE_SOURCES}) set_target_properties (yap-bin PROPERTIES OUTPUT_NAME yap) diff --git a/cmake/Prelims.cmake b/cmake/Prelims.cmake index 5e3bba6fb..41b6b4265 100644 --- a/cmake/Prelims.cmake +++ b/cmake/Prelims.cmake @@ -162,7 +162,6 @@ set(YAP_ROOTDIR "${prefix}") # include( Model NO_POLICY_SCOPE ) include (cudd NO-POLICY-SCOPE) -include (python NO-POLICY-SCOPE) include (java NO-POLICY-SCOPE) set (pl_library "" CACHE INTERNAL "prolog library files" ) diff --git a/cmake/python.cmake b/cmake/python.cmake index fa88ccce7..db355daaa 100644 --- a/cmake/python.cmake +++ b/cmake/python.cmake @@ -1,6 +1,7 @@ +set (Python_ADDITIONAL_VERSIONS 3.7 3.6 3.5 3.6 3.4 ) -option (WITH_PYTHON -"Allow Python->YAP and YAP->Python" ON) +find_package(PythonInterp) +# find_package(PythonLibs) # PYTHONLIBS_FOUND - have the Python libs been found @@ -11,67 +12,66 @@ option (WITH_PYTHON # PYTHONLIBS_VERSION_STRING - version of the Python libs found (since CMake 2.8.8) # # -IF (WITH_PYTHON) - set (Python_ADDITIONAL_VERSIONS 3.7 3.6 3.5 3.6 3.4 3.3) - find_package(PythonInterp) - # find_package(PythonLibs) +execute_process ( COMMAND ${PYTHON_EXECUTABLE} -c "import sysconfig; print( + sysconfig.get_path( 'include' ) )" + OUTPUT_VARIABLE _ABS_PYTHON_INCLUDE_PATH + OUTPUT_STRIP_TRAILING_WHITESPACE ) - - execute_process ( COMMAND ${PYTHON_EXECUTABLE} -c "import sysconfig; print( sysconfig.get_path( 'include' ) )" -OUTPUT_VARIABLE _ABS_PYTHON_INCLUDE_PATH -OUTPUT_STRIP_TRAILING_WHITESPACE ) get_filename_component ( ABS_PYTHON_INCLUDE_PATH ${_ABS_PYTHON_INCLUDE_PATH} ABSOLUTE ) - set ( PYTHON_INCLUDE_DIR - ${ABS_PYTHON_INCLUDE_PATH} - CACHE "PATH" "Directory with Python.h " - ) +set ( PYTHON_INCLUDE_DIR + ${ABS_PYTHON_INCLUDE_PATH} + CACHE "PATH" "Directory with Python.h " + ) - set ( PYTHON_INCLUDE_DIRS - ${ABS_PYTHON_INCLUDE_PATH} - CACHE "PATH" "Python.h Dir (Deprecated)" - ) +set ( PYTHON_INCLUDE_DIRS + ${ABS_PYTHON_INCLUDE_PATH} + CACHE "PATH" "Python.h Dir (Deprecated)" + ) - execute_process ( COMMAND ${PYTHON_EXECUTABLE} -c "import sysconfig; print( sysconfig.get_path( 'stdlib' ) )" - OUTPUT_VARIABLE _ABS_PYTHON_SYSLIB_PATH - OUTPUT_STRIP_TRAILING_WHITESPACE ) +execute_process ( COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_SOURCE_DIR}/cmake/libfind.py" + OUTPUT_VARIABLE ABS_PYTHON_SYSLIB + OUTPUT_STRIP_TRAILING_WHITESPACE ) -get_filename_component ( _ABS_PYTHON_SYSLIB_PATH ${_ABS_PYTHON_SYSLIB_PATH} ABSOLUTE ) -get_filename_component ( _ABS_PYTHON_SYSLIB_PATH ${_ABS_PYTHON_SYSLIB_PATH} DIRECTORY ) +set ( PYTHON_LIBRARY + ${ABS_PYTHON_SYSLIB} + CACHE "FILEPATH" "Python Library" + ) +set ( PYTHON_LIBRARIES + ${PYTHON_LIBRARY} + CACHE "FILEPATH" "Python Library (Deprecated)" + ) - find_library( ABS_PYTHON_SYSLIB_PATH - NAMES python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}m - PATHS ${_ABS_PYTHON_SYSLIB_PATH} ${libdir} - ) +if ( (EXISTS ${PYTHON_LIBRARY}) AND ( EXISTS ${PYTHON_INCLUDE_DIR}) ) + set ( PYTHONLIBS_FOUND ON + CACHE "BOOLEAN" "Python installed") + # else() - set ( PYTHON_LIBRARY - ${ABS_PYTHON_SYSLIB_PATH} - CACHE "FILEPATH" "Python Library" - ) - set ( PYTHON_LIBRARIES - ${PYTHON_LIBRARY} - CACHE "FILEPATH" "Python Library (Deprecated)" - ) - if ( (EXISTS ${PYTHON_LIBRARY}) AND ( EXISTS ${PYTHON_INCLUDE_DIR}) ) - set ( PYTHONLIBS_FOUND ON ) -# else() - -#find_package(PythonLibs) + #find_package(PythonLibs) endif() - macro_log_feature (PYTHONLIBS_FOUND "Python" - "Use Python System" - "http://www.python.org" FALSE ) +include_directories( BEFORE ${PYTHON_INCLUDE_DIR} ) + +LIST( APPEND + CMAKE_REQUIRED_INCLUDES ${PYTHON_INCLUDE_DIR} ${CMAKE_REQUIRED_INCLUDES}) - include_directories( BEFORE ${PYTHON_INCLUDE_DIR} ) +check_include_file(Python.h HAVE_PYTHON_H) - LIST( APPEND - CMAKE_REQUIRED_INCLUDES ${PYTHON_INCLUDE_DIR} ${CMAKE_REQUIRED_INCLUDES}) +IF (PYTHONLIBS_FOUND) + add_subDIRECTORY (packages/python) +ENDIF() - check_include_file(Python.h HAVE_PYTHON_H) +if (PYTHONLIBS_FOUND AND SWIG_FOUND) + add_subdirectory(packages/python/swig) + include(FindPythonModule) + find_python_module( jupyter ) + + if (PY_JUPYTER) + add_subdirectory(packages/python/yap_kernel) + ENDIF() +endif() -endif(WITH_PYTHON) diff --git a/include/YapError.h b/include/YapError.h index 315efd58a..fd3c1d6fd 100644 --- a/include/YapError.h +++ b/include/YapError.h @@ -231,7 +231,7 @@ INLINE_ONLY extern inline Term Yap_ensure_atom__(const char *fu, const char *fi, #define LOCAL_BallTerm LOCAL_ActiveError->errorTerm #define LOCAL_ErrorMessage LOCAL_ActiveError->errorMsg - extern bool Yap_find_prolog_culprit(); + extern bool Yap_find_prolog_culprit(void); extern yap_error_class_number Yap_errorClass(yap_error_number e); extern const char *Yap_errorName(yap_error_number e); extern const char *Yap_errorClassName(yap_error_class_number e); diff --git a/packages/python/CMakeLists.txt b/packages/python/CMakeLists.txt index 49328bef0..79cfe4dc2 100644 --- a/packages/python/CMakeLists.txt +++ b/packages/python/CMakeLists.txt @@ -1,43 +1,29 @@ #CHECK: PythonLibs, changed to work in WIN32 -if (PYTHONLIBS_FOUND) +set (PYTHON_SOURCES python.c pl2py.c pybips.c py2pl.c pl2pl.c pypreds.c) - include(FindPythonModule) +set (PYTHON_HEADERS python.h) - set (PYTHON_SOURCES python.c pl2py.c pybips.c py2pl.c pl2pl.c pypreds.c) +set (CMAKE_POSITION_INDEPENDENT_CODE TRUE) - set (PYTHON_HEADERS python.h) +add_library (YAPPython SHARED ${PYTHON_SOURCES}) - set (CMAKE_POSITION_INDEPENDENT_CODE TRUE) +set_property( SOURCE ${PYTHON_SOURCES} APPEND PROPERTY COMPILE_DEFINITIONS YAP_KERNEL=1) - add_library (YAPPython SHARED ${PYTHON_SOURCES}) +set (PYTHON_PL python.pl) - target_link_libraries(YAPPython libYap ${PYTHON_LIBRARY} ${WINDLLS} ${GMP_LIBRARIES}) +install(FILES python.pl DESTINATION ${libpl} ) - set_property( SOURCE ${PYTHON_SOURCES} APPEND PROPERTY COMPILE_DEFINITIONS YAP_KERNEL=1) +add_to_group( pl_library PYTHON_PL ) - set (PYTHON_PL python.pl) - - install(FILES python.pl DESTINATION ${libpl} ) - - add_to_group( pl_library PYTHON_PL ) - # configure_file ("setup.py.cmake" "setup.py" ) - set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/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 ) - - if (PY_JUPYTER) - - add_subdirectory(yap_kernel) - - ENDIF() - - IF(WIN32) +IF(WIN32) install(TARGETS YAPPython LIBRARY DESTINATION ${libdir} RUNTIME DESTINATION ${bindir} @@ -47,6 +33,5 @@ if (PYTHONLIBS_FOUND) LIBRARY DESTINATION ${libdir} RUNTIME DESTINATION ${libdir} ARCHIVE DESTINATION ${libdir} ) -endif() + endif() -endif (PYTHONLIBS_FOUND) diff --git a/packages/python/__main__.py b/packages/python/__main__.py index f7e95ef82..4c4c596fb 100644 --- a/packages/python/__main__.py +++ b/packages/python/__main__.py @@ -1,3 +1,4 @@ if __name__ == '__main__': from yapkernel import kernelapp as app + import pdbl pdb.set_trace() app.launch_new_instance() diff --git a/packages/python/pl2py.c b/packages/python/pl2py.c index 2dbc0aa09..15f501131 100644 --- a/packages/python/pl2py.c +++ b/packages/python/pl2py.c @@ -32,7 +32,7 @@ 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: { if (t==0) { diff --git a/packages/python/py2pl.c b/packages/python/py2pl.c index 0fe45324e..1012adfe8 100644 --- a/packages/python/py2pl.c +++ b/packages/python/py2pl.c @@ -1,6 +1,6 @@ #include "python.h" - + static foreign_t repr_term(PyObject *pVal, term_t t) { term_t to = PL_new_term_ref(), t1 = PL_new_term_ref(); PL_put_pointer(t1, pVal); @@ -25,25 +25,26 @@ 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); + // fputs(" <<*** ",stderr); PyObject_Print(pVal,stderr,0); fputs("<<***\n",stderr); if (pVal == Py_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); + //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)) { - rc = PL_unify_atom(t, ATOM_true); + rc = rc && PL_unify_atom(t, ATOM_true); } else { - rc = PL_unify_atom(t, ATOM_false); + rc = rc && PL_unify_atom(t, ATOM_false); } } else if (PyLong_Check(pVal)) { - rc = PL_unify_int64(t, PyLong_AsLong(pVal)); + rc = rc && PL_unify_int64(t, PyLong_AsLong(pVal)); #if PY_MAJOR_VERSION < 3 } else if (PyInt_Check(pVal)) { - rc = PL_unify_int64(t, PyInt_AsLong(pVal)); + rc = rc && PL_unify_int64(t, PyInt_AsLong(pVal)); #endif } else if (PyFloat_Check(pVal)) { - rc = PL_unify_float(t, PyFloat_AsDouble(pVal)); + rc = rc && PL_unify_float(t, PyFloat_AsDouble(pVal)); } else if (PyComplex_Check(pVal)) { term_t t1 = PL_new_term_ref(), t2 = PL_new_term_ref(); @@ -52,7 +53,7 @@ fputs(" <<*** ",stderr); PyObject_Print(pVal,stderr,0); fputs("<<***\n",st !PL_cons_functor(to, FUNCTOR_complex2, t1, t2)) { rc = false; } else { - rc = PL_unify(t, to); + rc = rc && PL_unify(t, to); } } else if (PyUnicode_Check(pVal)) { atom_t tmp_atom; @@ -67,41 +68,43 @@ fputs(" <<*** ",stderr); PyObject_Print(pVal,stderr,0); fputs("<<***\n",st const char *s = PyUnicode_AsUTF8(pVal); tmp_atom = PL_new_atom( s); #endif - rc = PL_unify_atom(t, tmp_atom); + rc = rc && PL_unify_atom(t, tmp_atom); } else if (PyByteArray_Check(pVal)) { atom_t tmp_atom = PL_new_atom(PyByteArray_AsString(pVal)); - rc = PL_unify_atom(t, tmp_atom); + rc = 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)); - rc = PL_unify_atom(t, tmp_atom); + rc = rc && PL_unify_atom(t, tmp_atom); #endif } else if (PyTuple_Check(pVal)) { Py_ssize_t i, sz = PyTuple_Size(pVal); functor_t f; const char *s; - if ((s = (Py_TYPE(pVal)->tp_name))) { - if (!strcmp(s, "H")) { - pVal = PyTuple_GetItem(pVal, 0); - if (pVal==NULL) { + if (sz == 0) { + rc = rc && PL_unify_atom(t, ATOM_brackets); + } else { + if ((s = (Py_TYPE(pVal)->tp_name))) { + if (!strcmp(s, "H")) { + pVal = PyTuple_GetItem(pVal, 0); + if (pVal==NULL) { pVal = Py_None; PyErr_Clear(); + } + } + if (s[0] == '$') { + char *ns = malloc(strlen(s) + 5); + strcpy(ns, "__"); + strcat(ns, s + 1); + strcat(ns, "__"); + f = PL_new_functor(PL_new_atom(ns), sz); + } else { + f = PL_new_functor(PL_new_atom(s), sz); } - } - if (s[0] == '$') { - char *ns = malloc(strlen(s) + 5); - strcpy(ns, "__"); - strcat(ns, s + 1); - strcat(ns, "__"); - f = PL_new_functor(PL_new_atom(ns), sz); } else { - f = PL_new_functor(PL_new_atom(s), sz); + f = PL_new_functor(ATOM_t, sz); } - } else { - f = PL_new_functor(ATOM_t, sz); - } if (PL_unify_functor(t, f)) { - rc = true; for (i = 0; i < sz; i++) { if (!PL_get_arg(i + 1, t, to)) rc = false; @@ -115,61 +118,69 @@ fputs(" <<*** ",stderr); PyObject_Print(pVal,stderr,0); fputs("<<***\n",st } else { rc = false; } - fputs(" ||*** ",stderr); Yap_DebugPlWrite(YAP_GetFromSlot(t)); fputs(" ||***\n",stderr); - } else if (PyList_Check(pVal)) { - YAP_Term yt = YAP_GetFromSlot(t); - Py_ssize_t i, sz = PyList_GET_SIZE(pVal); - - for (i = 0; i < sz; i++) { - 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); - + //fputs(" ||*** ",stderr); Yap_DebugPlWrite(YAP_GetFromSlot(t)); fputs(" ||***\n",stderr); } - rc = rc && PL_unify_nil(t); - fputs("[***] ", stderr); - Yap_DebugPlWrite(yt); fputs("[***]\n", stderr); + } else if (PyList_Check(pVal)) { + Py_ssize_t i, sz = PyList_GET_SIZE(pVal); + + if (sz == 0) { + rc = rc && PL_unify_atom(t, ATOM_nil); + } else { + for (i = 0; i < sz; i++) { + 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); + + } + 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; int left = PyDict_Size(pVal); PyObject *key, *value; - while (PyDict_Next(pVal, &pos, &key, &value)) { - term_t tkey = PL_new_term_ref(), tval = PL_new_term_ref(), tint, - tnew = PL_new_term_ref(); - /* do something interesting with the values... */ - if (!python_to_term(key, tkey)) { - continue; + if (left == 0) { + rc = rc && PL_unify_atom(t, ATOM_curly_brackets); + } else { + while (PyDict_Next(pVal, &pos, &key, &value)) { + term_t tkey = PL_new_term_ref(), tval = PL_new_term_ref(), tint, + tnew = PL_new_term_ref(); + /* do something interesting with the values... */ + if (!python_to_term(key, tkey)) { + continue; + } + if (!python_to_term(value, tval)) { + continue; + } + /* reuse */ + tint = tkey; + if (!PL_cons_functor(tint, FUNCTOR_colon2, tkey, tval)) { + rc = false; + continue; + } + if (--left) { + if (!PL_cons_functor(tint, FUNCTOR_comma2, tint, tnew)) + PL_reset_term_refs(tkey); + rc = false; + } + if (!PL_unify(ti, tint)) { + rc = false; } + ti = tnew; + PL_reset_term_refs(tkey); } - if (!python_to_term(value, tval)) { - continue; - } - /* reuse */ - tint = tkey; - if (!PL_cons_functor(tint, FUNCTOR_colon2, tkey, tval)) { - rc = false; - continue; - } - if (--left) { - if (!PL_cons_functor(tint, FUNCTOR_comma2, tint, tnew)) - PL_reset_term_refs(tkey); - rc = false; - } - if (!PL_unify(ti, tint)) { - rc = false; } - ti = tnew; - PL_reset_term_refs(tkey); + rc = rc && PL_unify(t, to); } - rc = PL_unify(t, to); } else { - rc = repr_term(pVal, t); + rc = rc && repr_term(pVal, t); } PL_reset_term_refs(to); return rc; diff --git a/packages/python/pybips.c b/packages/python/pybips.c index aa259d9e5..559e70ab3 100644 --- a/packages/python/pybips.c +++ b/packages/python/pybips.c @@ -41,11 +41,10 @@ PyObject *PythonLookupSpecial(const char *s) { 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) { + } + if (strcmp(s, "{}") == 0) { return PyDict_New(); /* return __main__,s */ } @@ -53,11 +52,9 @@ PyObject *PythonLookupSpecial(const char *s) { } PyObject *lookupPySymbol(const char *sp, PyObject *pContext, PyObject **duc) { - PyObject *out = NULL; + PyObject *out = Py_None; if (!sp) return Py_None; - if (strcmp(sp, "none") == 0) - return Py_None; if ((out = finalLookup(pContext, sp))) { return out; } @@ -70,7 +67,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))) { @@ -737,8 +734,10 @@ PyObject *term_to_nametuple(const char *s, arity_t arity, PyObject *tuple) { typp = PyMem_Malloc(sizeof(PyTypeObject)); PyStructSequence_Desc *desc = PyMem_Malloc(sizeof(PyStructSequence_Desc)); - - desc->name = PyUnicode_AsUTF8(key); + const char*name = PyUnicode_AsUTF8(key); + desc->name = PyMem_Malloc(strlen(name)+1); + strcpy(desc->name, name); + Py_DECREF(key); desc->doc = "YAPTerm"; desc->fields = pnull; desc->n_in_sequence = 32; @@ -748,7 +747,8 @@ PyObject *term_to_nametuple(const char *s, arity_t arity, PyObject *tuple) { typp->tp_repr = structseq_repr; // typp = PyStructSequence_NewType(desc); Py_INCREF(typp); - typp->tp_flags |= Py_TPFLAGS_HEAPTYPE; + Py_INCREF(desc); + //typp->tp_flags |= Py_TPFLAGS_HEAPTYPE; // don't do this: we cannot add a type as an atribute. //PyModule_AddObject(py_Main, s, (PyObject *)typp); if (py_F2P) @@ -759,10 +759,10 @@ 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); - } + //PyObject_Print(pArg,stderr,0);fputc('\n',stderr); + } ((PyStructSequence *)o)->ob_base.ob_size = arity; - PyObject_Print(o,stderr,0);fputc('\n',stderr); + //PyObject_Print(o,stderr,0);fputc('\n',stderr); return o; #else PyObject *o1; diff --git a/packages/python/python.c b/packages/python/python.c index 1d6e30a3e..4ca39c3ec 100644 --- a/packages/python/python.c +++ b/packages/python/python.c @@ -2,15 +2,15 @@ #include "python.h" atom_t ATOM_true, ATOM_false, ATOM_colon, ATOM_dot, ATOM_none, ATOM_t, - ATOM_comma, ATOM_builtin, ATOM_A, ATOM_V, ATOM_self; + ATOM_comma, ATOM_builtin, ATOM_A, ATOM_V, ATOM_self, ATOM_nil, ATOM_brackets, ATOM_curly_brackets; functor_t FUNCTOR_dollar1, FUNCTOR_abs1, FUNCTOR_all1, FUNCTOR_any1, - FUNCTOR_bin1, FUNCTOR_brackets1, FUNCTOR_comma2, FUNCTOR_dir1, - FUNCTOR_float1, FUNCTOR_int1, FUNCTOR_iter1, FUNCTOR_iter2, FUNCTOR_long1, - FUNCTOR_len1, FUNCTOR_curly1, FUNCTOR_ord1, FUNCTOR_range1, FUNCTOR_range2, - FUNCTOR_range3, FUNCTOR_sum1, FUNCTOR_pointer1, FUNCTOR_complex2, - FUNCTOR_plus2, FUNCTOR_sub2, FUNCTOR_mul2, FUNCTOR_div2, FUNCTOR_hat2, - FUNCTOR_colon2, FUNCTOR_comma2, FUNCTOR_equal2, FUNCTOR_sqbrackets2, + FUNCTOR_bin1, FUNCTOR_brackets1, FUNCTOR_comma2, FUNCTOR_dir1, + FUNCTOR_float1, FUNCTOR_int1, FUNCTOR_iter1, FUNCTOR_iter2, FUNCTOR_long1, + FUNCTOR_len1, FUNCTOR_curly1, FUNCTOR_ord1, FUNCTOR_range1, FUNCTOR_range2, + FUNCTOR_range3, FUNCTOR_sum1, FUNCTOR_pointer1, FUNCTOR_complex2, + FUNCTOR_plus2, FUNCTOR_sub2, FUNCTOR_mul2, FUNCTOR_div2, FUNCTOR_hat2, + FUNCTOR_colon2, FUNCTOR_comma2, FUNCTOR_equal2, FUNCTOR_sqbrackets2, FUNCTOR_dot2, FUNCTOR_brackets1; X_API PyObject *py_Builtin; @@ -53,7 +53,9 @@ static void install_py_constants(void) { ATOM_false = PL_new_atom("false"); ATOM_dot = PL_new_atom("."); ATOM_self = PL_new_atom("self"); - ATOM_t = PL_new_atom("t"); + ATOM_nil = PL_new_atom("[]"); + ATOM_brackets = PL_new_atom("()"); + ATOM_curly_brackets = PL_new_atom("{}"); FUNCTOR_abs1 = PL_new_functor(PL_new_atom("abs"), 1); FUNCTOR_all1 = PL_new_functor(PL_new_atom("all"), 1); FUNCTOR_any1 = PL_new_functor(PL_new_atom("any"), 1); diff --git a/packages/python/python.h b/packages/python/python.h index 583ad841e..a69b0906b 100644 --- a/packages/python/python.h +++ b/packages/python/python.h @@ -48,7 +48,7 @@ extern X_API PyObject *yap_to_python(YAP_Term t, bool eval, PyObject *o); typedef YAP_Arity arity_t; extern atom_t ATOM_true, ATOM_false, ATOM_colon, ATOM_dot, ATOM_none, ATOM_t, - ATOM_comma, ATOM_builtin, ATOM_V, ATOM_A, ATOM_self; + ATOM_comma, ATOM_builtin, ATOM_V, ATOM_A, ATOM_self, ATOM_nil, ATOM_brackets, ATOM_curly_brackets;; extern functor_t FUNCTOR_dollar1, FUNCTOR_abs1, FUNCTOR_all1, FUNCTOR_any1, FUNCTOR_bin1, FUNCTOR_brackets1, FUNCTOR_comma2, FUNCTOR_dir1, diff --git a/packages/python/swig/CMakeLists.txt b/packages/python/swig/CMakeLists.txt index 1c75eb540..3f2904cef 100644 --- a/packages/python/swig/CMakeLists.txt +++ b/packages/python/swig/CMakeLists.txt @@ -3,89 +3,109 @@ INCLUDE(NewUseSWIG) -if (PYTHONLIBS_FOUND) +include(FindPythonModule) - include(FindPythonModule) - file(RELATIVE_PATH RELATIVE_SOURCE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}) - INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH}) +file(RELATIVE_PATH RELATIVE_SOURCE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}) - INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/CXX") +configure_file("setup.py.cmake" ${CMAKE_CURRENT_BINARY_DIR}/setup.py) +configure_file("MANIFEST.in" ${CMAKE_CURRENT_BINARY_DIR}/MANIFEST.in) +foreach(i ${pl_library}) + get_filename_component(j ${i} NAME) + configure_file(${i} ${CMAKE_CURRENT_BINARY_DIR}/yap4py/prolog/${j}) +endforeach() +foreach(i ${pl_boot_library}) + get_filename_component(j ${i} NAME) + configure_file(${i} ${CMAKE_CURRENT_BINARY_DIR}/yap4py/prolog/pl/${j}) +endforeach() +foreach(i ${pl_os_library}) + get_filename_component(j ${i} NAME) + configure_file(${i} ${CMAKE_CURRENT_BINARY_DIR}/yap4py/prolog/os/${j}) +endforeach() +configure_file("${CMAKE_SOURCE_DIR}/README.md" ${CMAKE_CURRENT_BINARY_DIR}/README) +configure_file("__init__.py" ${CMAKE_CURRENT_BINARY_DIR}/yap4py/__init__.py) +configure_file("yapi.py" ${CMAKE_CURRENT_BINARY_DIR}/yap4py/yapi.py) +configure_file("yapi.yap" ${CMAKE_CURRENT_BINARY_DIR}/yap4py/prolog/yapi.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) +INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH}) +INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/CXX") - SWIG_ADD_LIBRARY(Py2YAP LANGUAGE python SHARED SOURCES ../yap.i ) - if (WIN32) +SET_SOURCE_FILES_PROPERTIES(../../swig/yap.i PROPERTIES CPLUSPLUS ON) +SET_SOURCE_FILES_PROPERTIES(../../swig/yap.i PROPERTIES SWIG_FLAGS "-O;-py3") +SET_SOURCE_FILES_PROPERTIES(../../swiyap.i PROPERTIES SWIG_MODULE_NAME yap) +SET_SOURCE_FILES_PROPERTIES(../../yap.i PROPERTIES OUTPUT_NAME yap) + +SWIG_ADD_LIBRARY(Py2YAP LANGUAGE python SHARED SOURCES ../../swig/yap.i ) +if (WIN32) SWIG_LINK_LIBRARIES(Py2YAP YAPPython libYap ${PYTHON_LIBRARIES} ) - else() + 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 + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + DEPENDS YAPPython YAPPython YAP++ + ) + # 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) - configure_file("setup.py.cmake" ${CMAKE_CURRENT_BINARY_DIR}/setup.py) + 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}) - # - # 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} - # ) + 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 - ) -set (dlls $ -$ -$ -$ -$ -$ -$) -if (TARGET real) + 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 +add_custom_target( YAP4PY ALL + ) - COMMAND ${PYTHON_EXECUTABLE} setup.py sdist bdist_wheel - VERBATIM - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - ) - if (WITH_DOCS AND DOXYGEN_FOUND) +add_custom_command (TARGET YAP4PY + COMMAND ${CMAKE_COMMAND} -E copy ${dlls} ${CMAKE_BINARY_DIR}/libYap${CMAKE_SHARED_LIBRARY_SUFFIX} ${CMAKE_BINARY_DIR}/${YAP_STARTUP} ${CMAKE_CURRENT_BINARY_DIR}/yap4py + COMMAND ${PYTHON_EXECUTABLE} setup.py clean sdist bdist_wheel + VERBATIM + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${CMAKE_BINARY_DIR}/${YAP_STARTUP} libYap ${dlls} ${pl_library} ${pl_boot_library} ${pl_os_library} yapi.py} + ) + + install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} -m pip install --no-index -f dist yap4py + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})" + DEPENDS Py4YAP${CMAKE_BINARY_DIR}/${YAP_STARTUP} ${dlls} ) + + + if (WITH_DOCS AND DOXYGEN_FOUND) set(CMAKE_SWIG_FLAGS -DDOXYGEN=${DOXYGEN_FOUND}) @@ -94,8 +114,8 @@ endif() 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} - ) + 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 @@ -108,4 +128,3 @@ endif() add_dependencies(${SWIG_MODULE_ftdi1_REAL_NAME} doc_i) ENDIF () -ENDIF () diff --git a/packages/python/swig/yapi.py b/packages/python/swig/yapi.py index 37622d095..9f7d58db6 100644 --- a/packages/python/swig/yapi.py +++ b/packages/python/swig/yapi.py @@ -48,21 +48,21 @@ def query_prolog(engine, s): while answer(q): # this new vs should contain bindings to vars vs= q.namedVars() - print( vs ) - gs = numbervars( engine, vs) - print(gs) - i=0 - # 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 - if name != binding: - print(name + " = " + str(binding)) - #ok, that was Prolog code - print("yes") + if vs != []: + gs = numbervars( engine, vs) + i=0 + # 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 + if name != binding: + print(name + " = " + str(binding)) + #ok, that was Prolog code + else: + print("yes") # deterministic = one solution if q.deterministic(): # done @@ -88,19 +88,21 @@ def query_prolog(engine, s): def live(): + yap_lib_path = os.path.dirname(__file__) args = yap.YAPEngineArgs() + args.setYapShareDir(os.path.join(yap_lib_path,"prolog")) 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') ) ) + engine = yap.YAPEngine(args) + engine.goal( use_module(library('yapi') ) ) loop = True while loop: try: s = input("?- ") if not s: loop = False - query_prolog(engine, s) + else: + query_prolog(engine, s) except SyntaxError as err: print("Syntax Error error: {0}".format(err)) except EOFError: @@ -117,4 +119,8 @@ def live(): # initialize engine # engine = yap.YAPEngine(); # engine = yap.YAPEngine(yap.YAPParams()); -live() +# +# + +if __name__ == "__main__": + live() diff --git a/packages/python/yap_kernel/CMakeLists.txt b/packages/python/yap_kernel/CMakeLists.txt index 0017f46fe..20eadabee 100644 --- a/packages/python/yap_kernel/CMakeLists.txt +++ b/packages/python/yap_kernel/CMakeLists.txt @@ -1,19 +1,44 @@ -configure_file ("setup.py.cmake" "setup.py" ) + + +set (PYTHON_SOURCES + __main__.py + __init__.py + setup.py + _version.py + interactiveshell.py + kernelapp.py +kernelspec.py +yapkernel.py ) + + +configure_file("setup.py" ${CMAKE_CURRENT_BINARY_DIR}/setup.py) +configure_file("MANIFEST.in" ${CMAKE_CURRENT_BINARY_DIR}/MANIFEST.in) +foreach(i ${PYTHON_SOURCES}) + configure_file(${i} ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/${i}) +endforeach() +configure_file("_version.py" ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/_version.py) +configure_file("YAP_KERNEL.md" ${CMAKE_CURRENT_BINARY_DIR}/README) +configure_file("${CMAKE_SOURCE_DIR}/docs/icons/yap_32x32x32.png" ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/resources/logo-32x32.png) +configure_file("${CMAKE_SOURCE_DIR}/docs/icons/yap_64x64x32.png" ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/resources/logo-64x64.png) +configure_file("${CMAKE_SOURCE_DIR}/misc/editors/prolog.js" ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/resources/prolog.js) set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py") +set( PYTHON_INSTALL sdist bdist_wheel) -add_custom_target ( YAPKernel ALL - COMMAND ${PYTHON_EXECUTABLE} setup.py build -f - DEPENDS yap_kernel.py - ) +add_custom_target( YAPKernel ALL + ) - set( PYTHON_INSTALL install) +add_custom_command (TARGET YAPKernel + COMMAND ${PYTHON_EXECUTABLE} setup.py clean sdist bdist_wheel + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS libYap ${SWIG_MODULE_Py2YAP_REAL_NAME} + ) -install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} ${PYTHON_INSTALL} -f - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})") +install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} -m pip install --no-index -f dist yap_kernel") + +install(FILES jupyter.yap + DESTINATION ${libpl} + ) - install(FILES jupyter.yap - DESTINATION ${libpl} - ) diff --git a/packages/python/yap_kernel/__main__.py b/packages/python/yap_kernel/__main__.py index 101460b76..6526e9b74 100644 --- a/packages/python/yap_kernel/__main__.py +++ b/packages/python/yap_kernel/__main__.py @@ -1,4 +1,4 @@ if __name__ == '__main__': - import yap_kernel.kernelapp - yap_kernel.kernelapp.launch_new_instance() + from yap_kernel.kernelapp import launch_new_instance + launch_new_instance() diff --git a/packages/python/yap_kernel/interactiveshell.py b/packages/python/yap_kernel/interactiveshell.py index 2e37043d6..7e6960df7 100644 --- a/packages/python/yap_kernel/interactiveshell.py +++ b/packages/python/yap_kernel/interactiveshell.py @@ -29,6 +29,7 @@ import types import subprocess import warnings import yap +import yap4py.yapi from io import open as io_open from pickleshare import PickleShareDB @@ -62,7 +63,7 @@ from IPython.core.prefilter import PrefilterManager from IPython.core.profiledir import ProfileDir from IPython.core.usage import default_banner from IPython.core.interactiveshell import InteractiveShellABC, InteractiveShell, ExecutionResult -from IPython.testing.skipdoctest import skip_doctest_py2, skip_doctest +from IPython.testing.skipdoctest import skip_doctest from IPython.utils import PyColorize from IPython.utils import io from IPython.utils import py3compat @@ -85,16 +86,34 @@ from traitlets import ( ) from warnings import warn from logging import error +from collections import namedtuple + + +use_module = namedtuple( 'use_module', 'file') +bindvars = namedtuple( 'bindvars', 'list') +library = namedtuple( 'library', 'list') +v = namedtuple( '_', 'slot') class YAPInteractiveShell: """An enhanced, interactive shell for YAP.""" def __init__(self, kernel): - self.yapeng = yap.YAPEngine() + + pjoin = os.path.join + here = os.path.abspath(os.path.dirname(__file__)) + yap_lib_path = pjoin(here, "../yap4py/prolog" ) + yap_dll_path = pjoin(here, "../yap4py" ) + args = yap.YAPEngineArgs() + args.setYapLibDir(yap_dll_path) + args.setYapShareDir(yap_lib_path) + #args.setYapPrologBootFile(os.path.join(yap_lib_path."startup.yss")) + self.yapeng = yap.YAPEngine( args ) self.q = None + self.yapeng.goal( use_module( library('yapi') ) ) self.shell = kernel.shell self.shell.run_cell = self.run_cell + def closeq(self): if self.q: self.q.close() @@ -105,26 +124,29 @@ class YAPInteractiveShell: """Run a complete IPython cell. Parameters - ---------- - raw_cell : str - The code (including IPython code such as %magic functions) to run. - store_history : bool + ---------- + raw_cell : str + The code (including IPython code such as %magic functions) to run. + store_history : bool If True, the raw and translated cell will be stored in IPython's - history. For user code calling back into IPython's machinery, this - should be set to False. - silent : bool + history. For user code calling back into IPython's machinery, this + should be set to False. + silent : bool If True, avoid side-effects, such as implicit displayhooks and - and logging. silent=True forces store_history=False. - shell_futures : bool + and logging. silent=True forces store_history=False. + shell_futures : bool If True, the code will share future statements with the interactive - shell. It will both be affected by previous __future__ imports, and - any __future__ imports in the code will affect the shell. If False, - __future__ imports are not shared in either direction. + shell. It will both be affected by previous __future__ imports, and + any __future__ imports in the code will affect the shell. If False, + __future__ imports are not shared in either direction. Returns - ------- - result : :class:`ExecutionResult` - """ + ------- + result : :class:`ExecutionResult` + """ + + def numbervars(self, l): + return self.yapeng.fun(bindvars(l)) result = ExecutionResult() @@ -161,19 +183,13 @@ class YAPInteractiveShell: # print('{0}'.format(f.getvalue())) # Execute the user code if run: - myvs = self.q.namedVarsCopy() + myvs = self.numbervars(self.q.namedVars()) if myvs: - i = 0 - for peq in myvs: - name = peq[0] - bind = peq[1] - if bind.isVar(): - var = yap.YAPAtom('$VAR') - f = yap.YAPFunctor(var, 1) - bind.unify(yap.YAPApplTerm(f, (name))) - else: - i = bind.numberVars(i, True) - print(name.text() + " = " + bind.text()) + for eq in myvs: + name = eq[0] + binding = eq[1] + if name != binding: + print(name + " = " + str(binding)) else: print("yes") if self.q.deterministic(): diff --git a/packages/python/yap_kernel/kernelapp.py b/packages/python/yap_kernel/kernelapp.py index c4eb3e66f..74e6fcfca 100644 --- a/packages/python/yap_kernel/kernelapp.py +++ b/packages/python/yap_kernel/kernelapp.py @@ -38,7 +38,7 @@ from jupyter_client.connect import ConnectionFileMixin # local imports from ipykernel.iostream import IOPubThread from ipykernel.heartbeat import Heartbeat -from .yap_kernel import YAPKernel +from yap_kernel.yapkernel import YAPKernel from ipykernel.parentpoller import ParentPollerUnix, ParentPollerWindows from jupyter_client.session import ( Session, session_flags, session_aliases, @@ -103,7 +103,7 @@ class YAPKernelApp(BaseIPythonApplication, InteractiveShellApp, flags = Dict(kernel_flags) classes = [YAPKernel, ZMQInteractiveShell, ProfileDir, Session] # the kernel class, as an importstring - kernel_class = Type('yap_kernel.yap_kernel.YAPKernel', + kernel_class = Type('yap_kernel.yapkernel.YAPKernel', klass='ipykernel.kernelbase.Kernel', help="""The Kernel subclass to be used. diff --git a/packages/python/yap_kernel/kernelspec.py b/packages/python/yap_kernel/kernelspec.py index fd2ac5ca4..b7f936579 100644 --- a/packages/python/yap_kernel/kernelspec.py +++ b/packages/python/yap_kernel/kernelspec.py @@ -1,490 +1,188 @@ -"""An Application for launching a kernel""" +"""The IPython kernel spec for Jupyter""" -# Copyright (c) YAP Development Team. +# Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from __future__ import print_function -import atexit +import errno +import json import os +import shutil import sys -import signal -import traceback -import logging +import tempfile -from tornado import ioloop -import zmq -from zmq.eventloop import ioloop as zmq_ioloop -from zmq.eventloop.zmqstream import ZMQStream +from jupyter_client.kernelspec import KernelSpecManager -from IPython.core.application import ( - BaseIPythonApplication, base_flags, base_aliases, catch_config_error -) +pjoin = os.path.join -from IPython.core.profiledir import ProfileDir -from IPython.core.shellapp import ( - InteractiveShellApp, shell_flags, shell_aliases -) +KERNEL_NAME = 'YAPKernel' -from IPython.utils import io -from ipython_genutils.path import filefind, ensure_dir_exists -from traitlets import ( - Any, Instance, Dict, Unicode, Integer, Bool, DottedObjectName, Type, default -) -from ipython_genutils.importstring import import_item -from jupyter_core.paths import jupyter_runtime_dir -from jupyter_client import write_connection_file -from jupyter_client.connect import ConnectionFileMixin +# path to kernelspec resources +RESOURCES = pjoin(os.path.dirname(__file__), 'resources') -# local imports -from ipykernel.iostream import IOPubThread -from ipykernel.heartbeat import Heartbeat -from .yap_kernel import YAPKernel -from ipykernel.parentpoller import ParentPollerUnix, ParentPollerWindows -from jupyter_client.session import ( - Session, session_flags, session_aliases, -) -from ipykernel.zmqshell import ZMQInteractiveShell -#----------------------------------------------------------------------------- -# Flags and Aliases -#----------------------------------------------------------------------------- +def make_yap_kernel_cmd(mod='yap_kernel', executable=None, extra_arguments=None, **kw): + """Build Popen command list for launching an IPython kernel. -kernel_aliases = dict(base_aliases) -kernel_aliases.update({ - 'ip' : 'YAPKernelApp.ip', - 'hb' : 'YAPKernelApp.hb_port', - 'shell' : 'YAPKernelApp.shell_port', - 'iopub' : 'YAPKernelApp.iopub_port', - 'stdin' : 'YAPKernelApp.stdin_port', - 'control' : 'YAPKernelApp.control_port', - 'f' : 'YAPKernelApp.connection_file', - 'transport': 'YAPKernelApp.transport', -}) + Parameters + ---------- + mod : str, optional (default 'yap_kernel') + A string of an IPython module whose __main__ starts an IPython kernel -kernel_flags = dict(base_flags) -kernel_flags.update({ - 'no-stdout' : ( - {'YAPKernelApp' : {'no_stdout' : True}}, - "redirect stdout to the null device"), - 'no-stderr' : ( - {'YAPKernelApp' : {'no_stderr' : True}}, - "redirect stderr to the null device"), - 'pylab' : ( - {'YAPKernelApp' : {'pylab' : 'auto'}}, - """Pre-load matplotlib and numpy for interactive use with - the default matplotlib backend."""), -}) + executable : str, optional (default sys.executable) + The Python executable to use for the kernel process. -# inherit flags&aliases for any IPython shell apps -kernel_aliases.update(shell_aliases) -kernel_flags.update(shell_flags) + extra_arguments : list, optional + A list of extra arguments to pass when executing the launch code. -# inherit flags&aliases for Sessions -kernel_aliases.update(session_aliases) -kernel_flags.update(session_flags) + Returns + ------- -_ctrl_c_message = """\ -NOTE: When using the `ipython kernel` entry point, Ctrl-C will not work. + A Popen command list + """ + if executable is None: + executable = sys.executable + extra_arguments = extra_arguments or [] + arguments = [executable, '-m', mod, '-f', '{connection_file}'] + arguments.extend(extra_arguments) -To exit, you will have to explicitly quit this process, by either sending -"quit" from a client, or using Ctrl-\\ in UNIX-like environments. + return arguments -To read more about this, see https://github.com/ipython/ipython/issues/2049 -""" - -#----------------------------------------------------------------------------- -# Application class for starting an YAP Kernel -#----------------------------------------------------------------------------- - -class YAPKernelApp(BaseIPythonApplication, InteractiveShellApp, - ConnectionFileMixin): - name='YAP-kernel' - aliases = Dict(kernel_aliases) - flags = Dict(kernel_flags) - classes = [YAPKernel, ZMQInteractiveShell, ProfileDir, Session] - # the kernel class, as an importstring - kernel_class = Type('yap_kernel.yap_kernel.YAPKernel', - klass='ipykernel.kernelbase.Kernel', - help="""The Kernel subclass to be used. - - This should allow easy re-use of the YAPKernelApp entry point - to configure and launch kernels other than YAP's own. - """).tag(config=True) - kernel = Any() - poller = Any() # don't restrict this even though current pollers are all Threads - heartbeat = Instance(Heartbeat, allow_none=True) - ports = Dict() - - subcommands = { - 'install': ( - 'yap_kernel.kernelspec.InstallYAPKernelSpecApp', - 'Install the YAP kernel' - ), +def get_kernel_dict(extra_arguments={'mod':'yap_kernel'}): + """Construct dict for kernel.json""" + return { + 'argv': make_yap_kernel_cmd(extra_arguments=extra_arguments), + 'display_name': 'YAPKernel 6', + 'language': 'prolog', } - # connection info: - connection_dir = Unicode() - @default('connection_dir') - def _default_connection_dir(self): - return jupyter_runtime_dir() +def write_kernel_spec(path=None, overrides=None, extra_arguments=None): + """Write a kernel spec directory to `path` - @property - def abs_connection_file(self): - if os.path.basename(self.connection_file) == self.connection_file: - return os.path.join(self.connection_dir, self.connection_file) - else: - return self.connection_file + If `path` is not specified, a temporary directory is created. + If `overrides` is given, the kernelspec JSON is updated before writing. - # streams, etc. - no_stdout = Bool(False, help="redirect stdout to the null device").tag(config=True) - no_stderr = Bool(False, help="redirect stderr to the null device").tag(config=True) - outstream_class = DottedObjectName('ipykernel.iostream.OutStream', - help="The importstring for the OutStream factory").tag(config=True) - displayhook_class = DottedObjectName('ipykernel.displayhook.ZMQDisplayHook', - help="The importstring for the DisplayHook factory").tag(config=True) + The path to the kernelspec is always returned. + """ + if path is None: + path = os.path.join(tempfile.mkdtemp(suffix='_kernels'), KERNEL_NAME) - # polling - parent_handle = Integer(int(os.environ.get('JPY_PARENT_PID') or 0), - help="""kill this process if its parent dies. On Windows, the argument - specifies the HANDLE of the parent process, otherwise it is simply boolean. - """).tag(config=True) - interrupt = Integer(int(os.environ.get('JPY_INTERRUPT_EVENT') or 0), - help="""ONLY USED ON WINDOWS - Interrupt this process when the parent is signaled. - """).tag(config=True) + # stage resources + shutil.copytree(RESOURCES, path) + # write kernel.json + kernel_dict = get_kernel_dict(extra_arguments) - def init_crash_handler(self): - sys.excepthook = self.excepthook + if overrides: + kernel_dict.update(overrides) + with open(pjoin(path, 'kernel.json'), 'w') as f: + json.dump(kernel_dict, f, indent=1) - def excepthook(self, etype, evalue, tb): - # write uncaught traceback to 'real' stderr, not zmq-forwarder - traceback.print_exception(etype, evalue, tb, file=sys.__stderr__) + return path - def init_poller(self): - if sys.platform == 'win32': - if self.interrupt or self.parent_handle: - self.poller = ParentPollerWindows(self.interrupt, self.parent_handle) - elif self.parent_handle: - self.poller = ParentPollerUnix() - def _bind_socket(self, s, port): - iface = '%s://%s' % (self.transport, self.ip) - if self.transport == 'tcp': - if port <= 0: - port = s.bind_to_random_port(iface) - else: - s.bind("tcp://%s:%i" % (self.ip, port)) - elif self.transport == 'ipc': - if port <= 0: - port = 1 - path = "%s-%i" % (self.ip, port) - while os.path.exists(path): - port = port + 1 - path = "%s-%i" % (self.ip, port) - else: - path = "%s-%i" % (self.ip, port) - s.bind("ipc://%s" % path) - return port +def install(kernel_spec_manager=None, user=False, kernel_name=KERNEL_NAME, display_name=None, + prefix=None, profile=None): + """Install the IPython kernelspec for Jupyter - def write_connection_file(self): - """write connection info to JSON file""" - cf = self.abs_connection_file - self.log.debug("Writing connection file: %s", cf) - write_connection_file(cf, ip=self.ip, key=self.session.key, transport=self.transport, - shell_port=self.shell_port, stdin_port=self.stdin_port, hb_port=self.hb_port, - iopub_port=self.iopub_port, control_port=self.control_port) + Parameters + ---------- - def cleanup_connection_file(self): - cf = self.abs_connection_file - self.log.debug("Cleaning up connection file: %s", cf) - try: - os.remove(cf) - except (IOError, OSError): - pass + kernel_spec_manager: KernelSpecManager [optional] + A KernelSpecManager to use for installation. + If none provided, a default instance will be created. + user: bool [default: False] + Whether to do a user-only install, or system-wide. + kernel_name: str, optional + Specify a name for the kernelspec. + This is needed for having multiple IPython kernels for different environments. + display_name: str, optional + Specify the display name for the kernelspec + profile: str, optional + Specify a custom profile to be loaded by the kernel. + prefix: str, optional + Specify an install prefix for the kernelspec. + This is needed to install into a non-default location, such as a conda/virtual-env. - self.cleanup_ipc_files() + Returns + ------- - def init_connection_file(self): - if not self.connection_file: - self.connection_file = "kernel-%s.json"%os.getpid() - try: - self.connection_file = filefind(self.connection_file, ['.', self.connection_dir]) - except IOError: - self.log.debug("Connection file not found: %s", self.connection_file) - # This means I own it, and I'll create it in this directory: - ensure_dir_exists(os.path.dirname(self.abs_connection_file), 0o700) - # Also, I will clean it up: - atexit.register(self.cleanup_connection_file) - return - try: - self.load_connection_file() - except Exception: - self.log.error("Failed to load connection file: %r", self.connection_file, exc_info=True) - self.exit(1) + The path where the kernelspec was installed. + """ + if kernel_spec_manager is None: + kernel_spec_manager = KernelSpecManager() - def init_sockets(self): - # Create a context, a session, and the kernel sockets. - self.log.info("Starting the kernel at pid: %i", os.getpid()) - context = zmq.Context.instance() - # Uncomment this to try closing the context. - # atexit.register(context.term) + if (kernel_name != KERNEL_NAME) and (display_name is None): + # kernel_name is specified and display_name is not + # default display_name to kernel_name + display_name = kernel_name + overrides = {} + if display_name: + overrides["display_name"] = display_name + if profile: + extra_arguments = ["--profile", profile] + if not display_name: + # add the profile to the default display name + overrides["display_name"] = 'Python %i [profile=%s]' % (sys.version_info[0], profile) + else: + extra_arguments = None + path = write_kernel_spec(overrides=overrides, extra_arguments=extra_arguments) + dest = kernel_spec_manager.install_kernel_spec( + path, kernel_name=kernel_name, user=user, prefix=prefix) + # cleanup afterward + shutil.rmtree(path) + return dest - self.shell_socket = context.socket(zmq.ROUTER) - self.shell_socket.linger = 1000 - self.shell_port = self._bind_socket(self.shell_socket, self.shell_port) - self.log.debug("shell ROUTER Channel on port: %i" % self.shell_port) +# Entrypoint - self.stdin_socket = context.socket(zmq.ROUTER) - self.stdin_socket.linger = 1000 - self.stdin_port = self._bind_socket(self.stdin_socket, self.stdin_port) - self.log.debug("stdin ROUTER Channel on port: %i" % self.stdin_port) +from traitlets.config import Application - self.control_socket = context.socket(zmq.ROUTER) - self.control_socket.linger = 1000 - self.control_port = self._bind_socket(self.control_socket, self.control_port) - self.log.debug("control ROUTER Channel on port: %i" % self.control_port) - self.init_iopub(context) +class InstallIPythonKernelSpecApp(Application): + """Dummy app wrapping argparse""" + name = 'ipython-kernel-install' - def init_iopub(self, context): - self.iopub_socket = context.socket(zmq.PUB) - self.iopub_socket.linger = 1000 - self.iopub_port = self._bind_socket(self.iopub_socket, self.iopub_port) - self.log.debug("iopub PUB Channel on port: %i" % self.iopub_port) - self.configure_tornado_logger() - self.iopub_thread = IOPubThread(self.iopub_socket, pipe=True) - self.iopub_thread.start() - # backward-compat: wrap iopub socket API in background thread - self.iopub_socket = self.iopub_thread.background_socket - - def init_heartbeat(self): - """start the heart beating""" - # heartbeat doesn't share context, because it mustn't be blocked - # by the GIL, which is accessed by libzmq when freeing zero-copy messages - hb_ctx = zmq.Context() - self.heartbeat = Heartbeat(hb_ctx, (self.transport, self.ip, self.hb_port)) - self.hb_port = self.heartbeat.port - self.log.debug("Heartbeat REP Channel on port: %i" % self.hb_port) - self.heartbeat.start() - - def log_connection_info(self): - """display connection info, and store ports""" - basename = os.path.basename(self.connection_file) - if basename == self.connection_file or \ - os.path.dirname(self.connection_file) == self.connection_dir: - # use shortname - tail = basename - else: - tail = self.connection_file - lines = [ - "To connect another client to this kernel, use:", - " --existing %s" % tail, - ] - # log connection info - # info-level, so often not shown. - # frontends should use the %connect_info magic - # to see the connection info - for line in lines: - self.log.info(line) - # also raw print to the terminal if no parent_handle (`ipython kernel`) - # unless log-level is CRITICAL (--quiet) - if not self.parent_handle and self.log_level < logging.CRITICAL: - io.rprint(_ctrl_c_message) - for line in lines: - io.rprint(line) - - self.ports = dict(shell=self.shell_port, iopub=self.iopub_port, - stdin=self.stdin_port, hb=self.hb_port, - control=self.control_port) - - def init_blackhole(self): - """redirects stdout/stderr to devnull if necessary""" - if self.no_stdout or self.no_stderr: - blackhole = open(os.devnull, 'w') - if self.no_stdout: - sys.stdout = sys.__stdout__ = blackhole - if self.no_stderr: - sys.stderr = sys.__stderr__ = blackhole - - def init_io(self): - """Redirect input streams and set a display hook.""" - if self.outstream_class: - outstream_factory = import_item(str(self.outstream_class)) - sys.stdout = outstream_factory(self.session, self.iopub_thread, u'stdout') - sys.stderr = outstream_factory(self.session, self.iopub_thread, u'stderr') - if self.displayhook_class: - displayhook_factory = import_item(str(self.displayhook_class)) - self.displayhook = displayhook_factory(self.session, self.iopub_socket) - sys.displayhook = self.displayhook - - self.patch_io() - - def patch_io(self): - """Patch important libraries that can't handle sys.stdout forwarding""" - try: - import faulthandler - except ImportError: - pass - else: - # Warning: this is a monkeypatch of `faulthandler.enable`, watch for possible - # updates to the upstream API and update accordingly (up-to-date as of Python 3.5): - # https://docs.python.org/3/library/faulthandler.html#faulthandler.enable - - # change default file to __stderr__ from forwarded stderr - faulthandler_enable = faulthandler.enable - def enable(file=sys.__stderr__, all_threads=True, **kwargs): - return faulthandler_enable(file=file, all_threads=all_threads, **kwargs) - - faulthandler.enable = enable - - if hasattr(faulthandler, 'register'): - faulthandler_register = faulthandler.register - def register(signum, file=sys.__stderr__, all_threads=True, chain=False, **kwargs): - return faulthandler_register(signum, file=file, all_threads=all_threads, - chain=chain, **kwargs) - faulthandler.register = register - - def init_signal(self): - signal.signal(signal.SIGINT, signal.SIG_IGN) - - def init_kernel(self): - """Create the Kernel object itself""" - shell_stream = ZMQStream(self.shell_socket) - control_stream = ZMQStream(self.control_socket) - - kernel_factory = self.kernel_class.instance - - kernel = kernel_factory(parent=self, session=self.session, - shell_streams=[shell_stream, control_stream], - iopub_thread=self.iopub_thread, - iopub_socket=self.iopub_socket, - stdin_socket=self.stdin_socket, - log=self.log, - profile_dir=self.profile_dir, - user_ns=self.user_ns, - ) - kernel.record_ports({ - name + '_port': port for name, port in self.ports.items() - }) - self.kernel = kernel - - # Allow the displayhook to get the execution count - self.displayhook.get_execution_count = lambda: kernel.execution_count - - def init_gui_pylab(self): - """Enable GUI event loop integration, taking pylab into account.""" - - # Register inline backend as default - # this is higher priority than matplotlibrc, - # but lower priority than anything else (mpl.use() for instance). - # This only affects matplotlib >= 1.5 - if not os.environ.get('MPLBACKEND'): - os.environ['MPLBACKEND'] = 'module://ipykernel.pylab.backend_inline' - - # Provide a wrapper for :meth:`InteractiveShellApp.init_gui_pylab` - # to ensure that any exception is printed straight to stderr. - # Normally _showtraceback associates the reply with an execution, - # which means frontends will never draw it, as this exception - # is not associated with any execute request. - - shell = self.shell - _showtraceback = shell._showtraceback - try: - # replace error-sending traceback with stderr - def print_tb(etype, evalue, stb): - print ("GUI event loop or pylab initialization failed", - file=sys.stderr) - print (shell.InteractiveTB.stb2text(stb), file=sys.stderr) - shell._showtraceback = print_tb - InteractiveShellApp.init_gui_pylab(self) - finally: - shell._showtraceback = _showtraceback - - def init_shell(self): - self.shell = getattr(self.kernel, 'shell', None) - if self.shell: - self.shell.configurables.append(self) - - def init_extensions(self): - super(YAPKernelApp, self).init_extensions() - # BEGIN HARDCODED WIDGETS HACK - # Ensure ipywidgets extension is loaded if available - extension_man = self.shell.extension_manager - if 'ipywidgets' not in extension_man.loaded: - try: - extension_man.load_extension('ipywidgets') - except ImportError as e: - self.log.debug('ipywidgets package not installed. Widgets will not be available.') - # END HARDCODED WIDGETS HACK - - def configure_tornado_logger(self): - """ Configure the tornado logging.Logger. - - Must set up the tornado logger or else tornado will call - basicConfig for the root logger which makes the root logger - go to the real sys.stderr instead of the capture streams. - This function mimics the setup of logging.basicConfig. - """ - logger = logging.getLogger('tornado') - handler = logging.StreamHandler() - formatter = logging.Formatter(logging.BASIC_FORMAT) - handler.setFormatter(formatter) - logger.addHandler(handler) - - @catch_config_error def initialize(self, argv=None): - super(YAPKernelApp, self).initialize(argv) - if self.subapp is not None: - return - # register zmq IOLoop with tornado - zmq_ioloop.install() - self.init_blackhole() - self.init_connection_file() - self.init_poller() - self.init_sockets() - self.init_heartbeat() - # writing/displaying connection info must be *after* init_sockets/heartbeat - self.write_connection_file() - # Log connection info after writing connection file, so that the connection - # file is definitely available at the time someone reads the log. - self.log_connection_info() - self.init_io() - self.init_signal() - self.init_kernel() - # shell init steps - self.init_path() - self.init_shell() - if self.shell: - self.init_gui_pylab() - self.init_extensions() - self.init_code() - # flush stdout/stderr, so that anything written to these streams during - # initialization do not get associated with the first execution request - sys.stdout.flush() - sys.stderr.flush() + if argv is None: + argv = sys.argv[1:] + self.argv = argv def start(self): - if self.subapp is not None: - return self.subapp.start() - if self.poller is not None: - self.poller.start() - self.kernel.start() + import argparse + parser = argparse.ArgumentParser(prog=self.name, + description="Install the IPython kernel spec.") + parser.add_argument('--user', action='store_true', + help="Install for the current user instead of system-wide") + parser.add_argument('--name', type=str, default=KERNEL_NAME, + help="Specify a name for the kernelspec." + " This is needed to have multiple IPython kernels at the same time.") + parser.add_argument('--display-name', type=str, + help="Specify the display name for the kernelspec." + " This is helpful when you have multiple IPython kernels.") + parser.add_argument('--profile', type=str, + help="Specify an IPython profile to load. " + "This can be used to create custom versions of the kernel.") + parser.add_argument('--prefix', type=str, + help="Specify an install prefix for the kernelspec." + " This is needed to install into a non-default location, such as a conda/virtual-env.") + parser.add_argument('--sys-prefix', action='store_const', const=sys.prefix, dest='prefix', + help="Install to Python's sys.prefix." + " Shorthand for --prefix='%s'. For use in conda/virtual-envs." % sys.prefix) + opts = parser.parse_args(self.argv) try: - ioloop.IOLoop.instance().start() - except KeyboardInterrupt: - pass - -launch_new_instance = YAPKernelApp.launch_instance - -def main(): - """Run an IPKernel as an application""" - app = YAPKernelApp.instance() - app.initialize() - app.start() + dest = install(user=opts.user, kernel_name=opts.name, profile=opts.profile, + prefix=opts.prefix, display_name=opts.display_name) + except OSError as e: + if e.errno == errno.EACCES: + print(e, file=sys.stderr) + if opts.user: + print("Perhaps you want `sudo` or `--user`?", file=sys.stderr) + self.exit(1) + raise + print("Installed kernelspec %s in %s" % (opts.name, dest)) if __name__ == '__main__': - main() + InstallIPythonKernelSpecApp.launch_instance() diff --git a/packages/python/yap_kernel/setup.py b/packages/python/yap_kernel/setup.py index 998a3744b..3ae6ea1d3 100644 --- a/packages/python/yap_kernel/setup.py +++ b/packages/python/yap_kernel/setup.py @@ -7,7 +7,7 @@ from __future__ import print_function # the name of the package -name = 'ipykernel' +name = 'yap_kernel' #----------------------------------------------------------------------------- # Minimal Python version sanity check @@ -56,7 +56,6 @@ setup_args = dict( version = version_ns['__version__'], scripts = glob(pjoin('scripts', '*')), packages = packages, - py_modules = ['ipykernel_launcher'], package_data = package_data, description = "IPython Kernel for Jupyter", author = 'IPython Development Team', @@ -80,12 +79,12 @@ if 'develop' in sys.argv or any(a.startswith('bdist') for a in sys.argv): import setuptools setuptools_args = {} -install_requires = setuptools_args['install_requires'] = [ - 'ipython>=4.0.0', - 'traitlets>=4.1.0', - 'jupyter_client', - 'tornado>=4.0', -] +# install_requires = setuptools_args['install_requires'] = [ +# 'ipython>=4.0.0', +# 'traitlets>=4.1.0', +# 'jupyter_client', +# 'tornado>=4.0', +# ] if any(a.startswith(('bdist', 'build', 'install')) for a in sys.argv): from ipykernel.kernelspec import write_kernel_spec, make_ipkernel_cmd, KERNEL_NAME diff --git a/packages/python/yap_kernel/yap_kernel.py b/packages/python/yap_kernel/yap_kernel.py deleted file mode 100644 index 4156545be..000000000 --- a/packages/python/yap_kernel/yap_kernel.py +++ /dev/null @@ -1,417 +0,0 @@ -from __future__ import print_function - -import signal -import yap -import io -import getpass -import sys -import traceback - -from IPython.core import release -from ipython_genutils.py3compat import builtin_mod, PY3, unicode_type, safe_unicode -from IPython.utils.tokenutil import token_at_cursor, line_at_cursor -from traitlets import Instance, Type, Any, List - -from ipykernel.comm import CommManager -from ipykernel.kernelbase import Kernel as KernelBase -from ipykernel.zmqshell import ZMQInteractiveShell -from .interactiveshell import YAPInteractiveShell -from IPython.core.interactiveshell import InteractiveShellABC, InteractiveShell -from contextlib import redirect_stdout - - - -kernel_json = { - "argv": [sys.executable, - "-m", "yap_kernel", - "-f", "{connection_file}"], - "display_name": " YAP-6.3", - "language": "prolog", - "name": "yap_kernel", -} - - -def eprint(*args, **kwargs): - print(*args, file=sys.stderr, **kwargs) - - -class YAPKernel(KernelBase): - shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', - allow_none=True) - shell_class = Type(ZMQInteractiveShell ) - user_ns = Instance(dict, args=None, allow_none=True) - def _user_ns_changed(self, name, old, new): - if self.shell is not None: - self.shell.user_ns = new - self.shell.init_user_ns() - - # A reference to the Python builtin 'raw_input' function. - # (i.e., __builtin__.raw_input for Python 2.7, builtins.input for Python 3) - _sys_raw_input = Any() - _sys_eval_input = Any() - - - implementation = 'YAP Kernel' - implementation_version = '1.0' - language = 'text' - language_version = '6.3' - banner = "YAP-6.3" - language_info = { - 'mimetype': 'text/prolog', - 'name': 'text', - # ------ If different from 'language': - 'codemirror_mode': { - "version": 2, - "name": "prolog" - }, - 'pygments_lexer': 'prolog', - 'version': "0.0.1", - 'file_extension': '.yap', - } - - -#------------------------------------------------------------------------- - # Things related to history management - #------------------------------------------------------------------------- - - - def __init__(self, **kwargs): - # sp = super(YAPKernel, self) - super(YAPKernel, self).__init__(**kwargs) - # Initialize the InteractiveShell subclass - self.shell = self.shell_class.instance(parent=self, - profile_dir = self.profile_dir, - user_ns = self.user_ns, - kernel = self, - ) - self.shell.displayhook.session = self.session - self.shell.displayhook.pub_socket = self.iopub_socket - self.shell.displayhook.topic = self._topic('execute_result') - self.shell.display_pub.session = self.session - self.shell.display_pub.pub_socket = self.iopub_socket - - self.comm_manager = CommManager(parent=self, kernel=self) - -# self.shell._last_traceback = None - self.shell.configurables.append(self.comm_manager) - comm_msg_types = [ 'comm_open', 'comm_msg', 'comm_close' ] - for msg_type in comm_msg_types: - self.shell_handlers[msg_type] = getattr(self.comm_manager, msg_type) - self.yap_shell = YAPInteractiveShell( self ) - - - def get_usage(self): - return "This is the YAP kernel." - - help_links = List([ - { - 'text': "Python", - 'url': "http://docs.python.org/%i.%i" % sys.version_info[:2], - }, - { - 'text': "YAP", - 'url': "http://YAP.org/documentation.html", - }, - { - 'text': "NumPy", - 'url': "http://docs.scipy.org/doc/numpy/reference/", - }, - { - 'text': "SciPy", - 'url': "http://docs.scipy.org/doc/scipy/reference/", - }, - { - 'text': "Matplotlib", - 'url': "http://matplotlib.org/contents.html", - }, - { - 'text': "SymPy", - 'url': "http://docs.sympy.org/latest/index.html", - }, - { - 'text': "pandas", - 'url': "http://pandas.pydata.org/pandas-docs/stable/", - }, - ]).tag(config=True) - - # Kernel info fields - implementation = 'YAP' - implementation_version = release.version - language_info = { - 'name': 'python', - 'version': sys.version.split()[0], - 'mimetype': 'text/x-python', - 'codemirror_mode': { - 'name': 'prolog', - 'version': sys.version_info[0] - }, - 'pygments_lexer': 'prolog', - 'nbconvert_exporter': 'python', - 'file_extension': '.yap' - } - - @property - def banner(self): - return self.shell.banner - - def start(self): - self.shell.exit_now = False - super(YAPKernel, self).start() - - def set_parent(self, ident, parent): - """Overridden from parent to tell the display hook and output streams - about the parent message. - """ - super(YAPKernel, self).set_parent(ident, parent) - self.shell.set_parent(parent) - - def init_metadata(self, parent): - """Initialize metadata. - - Run at the beginning of each execution request. - """ - md = super(YAPKernel, self).init_metadata(parent) - # FIXME: remove deprecated ipyparallel-specific code - # This is required for ipyparallel < 5.0 - md.update({ - 'dependencies_met' : True, - 'engine' : self.ident, - }) - return md - - def finish_metadata(self, parent, metadata, reply_content): - """Finish populating metadata. - - Run after completing an execution request. - """ - # FIXME: remove deprecated ipyparallel-specific code - # This is required by ipyparallel < 5.0 - metadata['status'] = reply_content['status'] - if reply_content['status'] == 'error' and reply_content['ename'] == 'UnmetDependency': - metadata['dependencies_met'] = False - - return metadata - - def _forward_input(self, allow_stdin=False): - """Forward raw_input and getpass to the current frontend. - - via input_request - """ - self._allow_stdin = allow_stdin - - if PY3: - self._sys_raw_input = builtin_mod.input - builtin_mod.input = self.raw_input - else: - self._sys_raw_input = builtin_mod.raw_input - self._sys_eval_input = builtin_mod.input - builtin_mod.raw_input = self.raw_input - builtin_mod.input = lambda prompt='': eval(self.raw_input(prompt)) - self._save_getpass = getpass.getpass - getpass.getpass = self.getpass - - def _restore_input(self): - """Restore raw_input, getpass""" - if PY3: - builtin_mod.input = self._sys_raw_input - else: - builtin_mod.raw_input = self._sys_raw_input - builtin_mod.input = self._sys_eval_input - - getpass.getpass = self._save_getpass - - @property - def execution_count(self): - return self.shell.execution_count - - @execution_count.setter - def execution_count(self, value): - # Ignore the incrememnting done by KernelBase, in favour of our shell's - # execution counter. - pass - - def do_execute(self, code, silent, store_history=True, - user_expressions=None, allow_stdin=False): - shell = self.shell # we'll need this a lot here - - self._forward_input(allow_stdin) - - reply_content = {} - try: - res = shell.run_cell(code, store_history=store_history, silent=silent) - finally: - self._restore_input() - - if res.error_before_exec is not None: - err = res.error_before_exec - else: - err = res.error_in_exec - - if res.success: - reply_content[u'status'] = u'ok' - elif isinstance(err, KeyboardInterrupt): - reply_content[u'status'] = u'aborted' - else: - reply_content[u'status'] = u'error' - - reply_content.update({ - # u'traceback': shell._last_traceback or [], - u'ename': unicode_type(type(err).__name__), - u'evalue': safe_unicode(err), - }) - - # FIXME: deprecate piece for ipyparallel: - e_info = dict(engine_uuid=self.ident, engine_id=self.int_id, - method='execute') - reply_content['engine_info'] = e_info - - - # Return the execution counter so clients can display prompts - reply_content['execution_count'] = shell.execution_count - 1 - - if 'traceback' in reply_content: - self.log.info("Exception in execute request:\n%s", '\n'.join(reply_content['traceback'])) - - - # At this point, we can tell whether the main code execution succeeded - # or not. If it did, we proceed to evaluate user_expressions - if reply_content['status'] == 'ok': - reply_content[u'user_expressions'] = \ - shell.user_expressions(user_expressions or {}) - else: - # If there was an error, don't even try to compute expressions - reply_content[u'user_expressions'] = {} - - # Payloads should be retrieved regardless of outcome, so we can both - # recover partial output (that could have been generated early in a - # block, before an error) and always clear the payload system. - reply_content[u'payload'] = shell.payload_manager.read_payload() - # Be aggressive about clearing the payload because we don't want - # it to sit in memory until the next execute_request comes in. - shell.payload_manager.clear_payload() - - return reply_content - - def do_complete(self, code, cursor_pos): - # FIXME: YAP completers currently assume single line, - # but completion messages give multi-line context - # For now, extract line from cell, based on cursor_pos: - if cursor_pos is None: - cursor_pos = len(code) - line, offset = line_at_cursor(code, cursor_pos) - line_cursor = cursor_pos - offset - - txt, matches = self.shell.complete('', line, line_cursor) - return {'matches' : matches, - 'cursor_end' : cursor_pos, - 'cursor_start' : cursor_pos - len(txt), - 'metadata' : {}, - 'status' : 'ok'} - - def do_inspect(self, code, cursor_pos, detail_level=0): - name = token_at_cursor(code, cursor_pos) - info = self.shell.object_inspect(name) - - reply_content = {'status' : 'ok'} - reply_content['data'] = data = {} - reply_content['metadata'] = {} - reply_content['found'] = info['found'] - if info['found']: - info_text = self.shell.object_inspect_text( - name, - detail_level=detail_level, - ) - data['text/plain'] = info_text - - return reply_content - - def do_history(self, hist_access_type, output, raw, session=0, start=0, - stop=None, n=None, pattern=None, unique=False): - if hist_access_type == 'tail': - hist = self.shell.history_manager.get_tail(n, raw=raw, output=output, - include_latest=True) - - elif hist_access_type == 'range': - hist = self.shell.history_manager.get_range(session, start, stop, - raw=raw, output=output) - - elif hist_access_type == 'search': - hist = self.shell.history_manager.search( - pattern, raw=raw, output=output, n=n, unique=unique) - else: - hist = [] - - return { - 'status': 'ok', - 'history' : list(hist), - } - - def do_shutdown(self, restart): - self.shell.exit_now = True - return dict(status='ok', restart=restart) - - def do_is_complete(self, code): - status, indent_spaces = self.shell.input_transformer_manager.check_complete(code) - r = {'status': status} - if status == 'incomplete': - r['indent'] = ' ' * indent_spaces - return r - - def do_apply(self, content, bufs, msg_id, reply_metadata): - from .serialize import serialize_object, unpack_apply_message - shell = self.shell - try: - working = shell.user_ns - - prefix = "_"+str(msg_id).replace("-","")+"_" - - f,args,kwargs = unpack_apply_message(bufs, working, copy=False) - - fname = getattr(f, '__name__', 'f') - - fname = prefix+"f" - argname = prefix+"args" - kwargname = prefix+"kwargs" - resultname = prefix+"result" - - ns = { fname : f, argname : args, kwargname : kwargs , resultname : None } - # print ns - working.update(ns) - code = "%s = %s(*%s,**%s)" % (resultname, fname, argname, kwargname) - try: - exec(code, shell.user_global_ns, shell.user_ns) - result = working.get(resultname) - finally: - for key in ns: - working.pop(key) - - result_buf = serialize_object(result, - buffer_threshold=self.session.buffer_threshold, - item_threshold=self.session.item_threshold, - ) - - except BaseException as e: - # invoke YAP traceback formatting - shell.showtraceback() - reply_content = { - u'traceback': shell._last_traceback or [], - u'ename': unicode_type(type(e).__name__), - u'evalue': safe_unicode(e), - } - # FIXME: deprecate piece for ipyparallel: - e_info = dict(engine_uuid=self.ident, engine_id=self.int_id, method='apply') - reply_content['engine_info'] = e_info - - self.send_response(self.iopub_socket, u'error', reply_content, - ident=self._topic('error')) - self.log.info("Exception in apply request:\n%s", '\n'.join(reply_content['traceback'])) - result_buf = [] - reply_content['status'] = 'error' - else: - reply_content = {'status' : 'ok'} - - return reply_content, result_buf - - def do_clear(self): - self.shell.reset(False) - return dict(status='ok') diff --git a/packages/swig/CMakeLists.txt b/packages/swig/CMakeLists.txt index b451e3a98..87d7f15c7 100644 --- a/packages/swig/CMakeLists.txt +++ b/packages/swig/CMakeLists.txt @@ -1,36 +1,21 @@ -option (WITH_SWiG - "Allow Python->YAP and Java->YAP" ON) +# +# SWIG_FOUND - set to true if SWIG is found +# SWIG_DIR - the directory where swig is installed +# SWIG_EXECUTABLE - the path to the swig executable +# SWIG_VERSION - the version number of the swig executable +# -IF (WITH_SWiG) +# This is a CMake example for Python and Java -find_host_package (SWIG) -macro_log_feature (SWIG_FOUND "Swig" - "Use SWIG Interface Generator " -"http://www.swig.org" ON) - -if (SWIG_FOUND) - # - # SWIG_FOUND - set to true if SWIG is found - # SWIG_DIR - the directory where swig is installed - # SWIG_EXECUTABLE - the path to the swig executable - # SWIG_VERSION - the version number of the swig executable - # - - # This is a CMake example for Python and Java - - INCLUDE(${SWIG_USE_FILE}) +INCLUDE(${SWIG_USE_FILE}) if (ANDROID) -add_subdirectory(android) + add_subdirectory(android) else(ANDROID) -add_subdirectory(python) -#add_subdirectory(java) + # add_subdirectory(java) endif(ANDROID) - set_property( DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS SWIGYAP=1) +set_property( DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS SWIGYAP=1) -endif (SWIG_FOUND) - -ENDIF (WITH_SWiG) diff --git a/packages/swig/yap.i b/packages/swig/yap.i index fd6c4c5c8..414229875 100644 --- a/packages/swig/yap.i +++ b/packages/swig/yap.i @@ -16,7 +16,7 @@ class YAPPredicate; class YAPEngine; -#define arity_t uintptr_t +#define arity_t size_t diff --git a/pl/CMakeLists.txt b/pl/CMakeLists.txt index 02eb3f89b..0cbc83513 100644 --- a/pl/CMakeLists.txt +++ b/pl/CMakeLists.txt @@ -7,7 +7,6 @@ atoms.yap attributes.yap boot.yap bootlists.yap -bootutils.yap callcount.yap checker.yap consult.yap @@ -21,6 +20,10 @@ directives.yap eam.yap error.yap errors.yap + + + + eval.yap flags.yap grammar.yap @@ -60,16 +63,18 @@ yio.yap add_to_group( pl_boot_library PL_SOURCES ) -add_custom_target (${YAP_STARTUP} ALL SOURCES ${PL_SOURCES} ${YAPOS_PL_SOURCES} WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) + add_custom_target (STARTUP ALL SOURCES + DEPENDS ${CMAKE_BINARY_DIR}/startup.yss + ) -if ( NOT CMAKE_CROSSCOMPILING ) -# Create a startup.yss on the top directory. -add_custom_command (TARGET ${YAP_STARTUP} - COMMAND yap-bin -B - VERBATIM - WORKING_DIRECTORY ${CMAKE_TOP_BINARY_DIR} - DEPENDS yap-bin ${PL_SOURCES} - ) + if ( NOT CMAKE_CROSSCOMPILING ) + # Create a startup.yss on the top directory. + add_custom_command (OUTPUT ${CMAKE_BINARY_DIR}/startup.yss + COMMAND yap-bin -B + VERBATIM + WORKING_DIRECTORY ${CMAKE_TOP_BINARY_DIR} + DEPENDS yap-bin ${PL_SOURCES} + ) endif ( NOT CMAKE_CROSSCOMPILING ) diff --git a/pl/absf.yap b/pl/absf.yap index f97f6b60e..3c2332844 100755 --- a/pl/absf.yap +++ b/pl/absf.yap @@ -173,7 +173,7 @@ absolute_file_name(File0,File) :- current_prolog_flag(open_expands_filename, OldF), current_prolog_flag( fileerrors, PreviousFileErrors ), current_prolog_flag( verbose_file_search, PreviousVerbose ), - get_abs_file_parameter( verbose_file_search, Opts, Verbose ), + get_abs_file_parameter( verbose_file_search, Opts,Verbose ), get_abs_file_parameter( expand, Opts, Expand ), set_prolog_flag( verbose_file_search, Verbose ), get_abs_file_parameter( file_errors, Opts, FErrors ), @@ -267,8 +267,25 @@ absolute_file_name(File0,File) :- '$dir', { '$absf_trace'(' ~w next', [P0]) }, '$cat_file_name'(P0, E). -'$file_name'(Name, _Opts, E) --> - '$cat_file_name'(Name, E). +'$file_name'(Name, Opts, E) --> + '$cat_file_name'(Name, E ). + /* + ( + { + get_abs_file_parameter( file_type, Opts, Lib ), + nonvar(Lib) + } + -> + { user:file_search_path(Lib, IDirs) }, + { '$paths'(IDirs, Dir ) }, + '$absf_trace'(' ~w first', [Dir]), + '$file_name'(Dir, Opts, _), + '$dir', + { '$absf_trace'(' ~w next', [P0]) } + ; + [] + ). + */ '$cat_file_name'(A/B, E ) --> @@ -417,12 +434,12 @@ absolute_file_name(File0,File) :- user:library_directory( Dir ). % '$split_by_sep'(0, 0, Dirs, Dir). '$system_library_directories'(foreign, Dir) :- - foreign_directory( Dir ). + user:foreign_directory( Dir ). % compatibility with old versions % % search the current directory first. '$system_library_directories'(commons, Dir) :- - commons_directory( Dir ). + user:commons_directory( Dir ). % enumerate all paths separated by a path_separator. diff --git a/pl/pathconf.yap b/pl/pathconf.yap index 64b62fbf0..76dce2d82 100644 --- a/pl/pathconf.yap +++ b/pl/pathconf.yap @@ -6,6 +6,7 @@ @{ **/ +:- module(user). /** @pred library_directory(?Directory:atom) is nondet, dynamic @@ -26,6 +27,9 @@ system_library/1. %% Specifies the set of directories where % one can find Prolog libraries. % +library_directory(Home) :- + current_prolog_flag(prolog_library_directory, Home), + Home \= ''. % 1. honor YAPSHAREDIR library_directory( Dir ) :- getenv( 'YAPSHAREDIR', Dir). @@ -44,8 +48,11 @@ library_directory( Dir ) :- This directory is initialized as a rule that calls the system predicate library_directories/2. + */ :- dynamic commons_directory/1. +:- multifile commons_directory/1. + commons_directory( Path ):- system_commons( Path ). @@ -63,6 +70,12 @@ commons_directory( Path ):- :- dynamic foreign_directory/1. +%foreign_directory( Path ):- +foreign_directory(Home) :- + current_prolog_flag(prolog_foreign_directory, Home), + Home \= ''. +foreign_directory( '.'). +foreign_directory(yap('lib/Yap')). foreign_directory( Path ):- system_foreign( Path ). @@ -126,6 +139,8 @@ file_search_path(system, Dir) :- prolog_flag(host_type, Dir). file_search_path(foreign, Dir) :- foreign_directory(Dir). +file_search_path(executable, Dir) :- + foreign_directory(Dir). file_search_path(path, C) :- ( getenv('PATH', A), ( current_prolog_flag(windows, true) @@ -142,11 +157,11 @@ file_search_path(path, C) :- whereas 'compile(system(A))` would look at the `host_type` flag. */ -:- module(user). :- multifile file_search_path/2. :- dynamic file_search_path/2. + file_search_path(library, Dir) :- library_directory(Dir). file_search_path(commons, Dir) :- @@ -157,8 +172,10 @@ file_search_path(yap, Home) :- current_prolog_flag(home, Home). file_search_path(system, Dir) :- prolog_flag(host_type, Dir). -file_search_path(foreign, '.'). -file_search_path(foreign, yap('lib/Yap')). +file_search_path(foreign, Dir) :- + foreign_directory(Dir). +file_search_path(executable, Dir) :- + foreign_directory(Dir). file_search_path(path, C) :- ( getenv('PATH', A), ( current_prolog_flag(windows, true)