This commit is contained in:
Vitor Santos Costa 2017-12-20 00:29:15 +00:00
parent 4a5002091f
commit 814aa2bd4c
10 changed files with 796 additions and 960 deletions

View File

@ -146,7 +146,8 @@ static void do_bootfile(const char *b_file USES_REGS) {
* `@` query user option.
*
*/
const char *rootdirs[] = {"[root]", "(execdir)..", "/usr/local", "~", NULL};
const char *rootdirs[] = {"[root]", "(execdir)..", "/usr/local", "/", "/usr",
"/opt", "$HOME", "$PWD", NULL};
const char *bindirs[] = {"[bin]", "(root)bin", NULL};
@ -162,17 +163,17 @@ const char *sharedirs[] = {
#endif
"[share]", "(root)share", NULL};
const char *dlldirs[] = {"$YAPLIBDIR", "(lib)Yap", ".", NULL};
const char *dlldirs[] = {"$YAPLIBDIR", "(lib)Yap", "$PWD", NULL};
const char *ssdirs[] = {".", "$YAPLIBDIR", "(lib)Yap", NULL};
const char *ssdirs[] = {"$PWD", "$YAPLIBDIR", "(lib)Yap", NULL};
const char *pldirs[] = {"$YAPSHAREDIR", "?library", "(share)Yap", ".", NULL};
const char *pldirs[] = {"$YAPSHAREDIR", "?library", "(share)Yap", "$PWD", NULL};
const char *bootpldirs[] = {"(pl)pl", ".", NULL};
const char *bootpldirs[] = {"(pl)pl", "$PWD", NULL};
const char *bootstrappldirs[] = {YAP_PL_SRCDIR, NULL};
const char *commonsdirs[] = {"(share)PrologCommons", ".", NULL};
const char *commonsdirs[] = {"(share)PrologCommons", "$PWD", NULL};
const char *ssnames[] = {"@SavedState", YAP_STARTUP, "startup.yss", NULL};
@ -213,7 +214,7 @@ char *location(YAP_init_args *iap, const char *inp, char *out) {
strcat(out, "/");
strcat(out, inp + strlen("(pl)"));
} else if (strstr(inp + 1, "execdir") == inp + 1) {
char *buf = Malloc(YAP_FILENAME_MAX+1);
char *buf = Malloc(YAP_FILENAME_MAX + 1);
const char *ex = Yap_AbsoluteFile(Yap_FindExecutable(), buf, false);
if (ex != NULL) {
strcpy(out, dirname((char *)ex));
@ -256,40 +257,40 @@ char *location(YAP_init_args *iap, const char *inp, char *out) {
}
}
} else if (inp[0] == '[') {
char *o = out;
const char *e;
if ((e = getenv("DESTDIR"))) {
strcpy(out, e);
o += strlen(e);
}
if (strstr(inp + 1, "root") == inp + 1) {
#ifdef YAP_ROOTDIR
strcpy(o, YAP_ROOTDIR);
#endif
} else if (strstr(inp + 1, "lib") == inp + 1) {
#ifdef YAP_LIBDIR
strcpy(o, YAP_LIBDIR);
#endif
} else if (strstr(inp + 1, "share") == inp + 1) {
#ifdef YAP_SHAREDIR
strcpy(o, YAP_SHAREDIR);
#endif
} else if (strstr(inp + 1, "dll") == inp + 1) {
#ifdef YAP_DLLDIR
strcpy(o, YAP_DLLDIR);
#endif
} else if (strstr(inp + 1, "pl") == inp + 1) {
#ifdef YAP_PLDIR
strcpy(o, YAP_PLDIR);
#endif
} else if (strstr(inp + 1, "commons") == inp + 1) {
#ifdef YAP_COMMONSDIR
strcpy(o, YAP_COMMONSDIR);
#endif
}
} else {
strcpy(out, inp);
char *o = out;
const char *e;
if ((e = getenv("DESTDIR"))) {
strcpy(out, e);
o += strlen(e);
}
if (strstr(inp + 1, "root") == inp + 1) {
#ifdef YAP_ROOTDIR
strcpy(o, YAP_ROOTDIR);
#endif
} else if (strstr(inp + 1, "lib") == inp + 1) {
#ifdef YAP_LIBDIR
strcpy(o, YAP_LIBDIR);
#endif
} else if (strstr(inp + 1, "share") == inp + 1) {
#ifdef YAP_SHAREDIR
strcpy(o, YAP_SHAREDIR);
#endif
} else if (strstr(inp + 1, "dll") == inp + 1) {
#ifdef YAP_DLLDIR
strcpy(o, YAP_DLLDIR);
#endif
} else if (strstr(inp + 1, "pl") == inp + 1) {
#ifdef YAP_PLDIR
strcpy(o, YAP_PLDIR);
#endif
} else if (strstr(inp + 1, "commons") == inp + 1) {
#ifdef YAP_COMMONSDIR
strcpy(o, YAP_COMMONSDIR);
#endif
}
} else {
strcpy(out, inp);
}
if (out[0]) {
return out;
}
@ -319,7 +320,6 @@ static const char *find_directory(YAP_init_args *iap, const char *paths[],
}
int i = 0;
while ((inp = paths[i++]) != NULL) {
printf("%s\n", inp);
out[0] = '\0';
char *o = location(iap, inp, out), *no;
if (o && o[0] && Yap_isDirectory(o)) {
@ -330,7 +330,7 @@ static const char *find_directory(YAP_init_args *iap, const char *paths[],
int j = 0;
while ((p = names[j++])) {
char *io = o + s;
printf("-> %s\n", o);
printf("%s -> %s\n", inp, o);
if ((no = location(iap, p, io)) && io[0] != '\0' && Yap_Exists(o))
return pop_output_text_stack(lvl, realpath(o, full));
}
@ -347,31 +347,27 @@ static const char *find_directory(YAP_init_args *iap, const char *paths[],
static void Yap_set_locations(YAP_init_args *iap) {
#if CONDA_BUILD
if (!getenv("DESTDIR")) {
char *buf = Malloc( YAP_FILENAME_MAX + 1);
const char *o = Yap_FindExecutable();
if (!o)
return;
o = Yap_AbsoluteFile(o, buf, false);
Int i = strlen(o);
while (--i) {
if (Yap_dir_separator((int)o[i]))
break;
}
if (i == 0) { setenv("DESTDIR", "/", 1); }
else {
while (--i) {
if (Yap_dir_separator((int)o[i]))
break;
}
if (i == 0) { setenv("DESTDIR", "/", 1); }
else { setenv("DESTDIR", o, 1); }
}
setenv("DESTDIR", buf, 1);
int lvl = push_text_stack();
const char *path = getenv("PATH");
char *o = &path[0L], *no, *p;
char *buf = Malloc(YAP_FILENAME_MAX + 1);
o = Malloc(strlen(path) + 1);
strcpy(o, path);
if ((p = strstr(o, "anaconda"))) {
char *q = p + strlen("anaconda"), *r = strstr(q, "/bin");
if (r - q > 0 && r - q < 10 && (r[4] == ':' || r[4] == '\0')) {
r[0] = '\0';
q = strrchr(o, ':');
if (q)
o = q + 1;
} else
o = NULL;
}
Yap_ROOTDIR = pop_output_text_stack(lvl, o);
}
if (!Yap_ROOTDIR)
#endif
Yap_ROOTDIR = find_directory(iap, rootdirs, NULL);
Yap_ROOTDIR = find_directory(iap, rootdirs, NULL);
Yap_LIBDIR = find_directory(iap, libdirs, NULL);
Yap_BINDIR = find_directory(iap, bindirs, NULL);
Yap_SHAREDIR = find_directory(iap, sharedirs, NULL);
@ -384,13 +380,14 @@ static void Yap_set_locations(YAP_init_args *iap) {
else
Yap_BOOTFILE = find_directory(iap, bootpldirs, plnames);
if (Yap_ROOTDIR)
setAtomicGlobalPrologFlag(HOME_FLAG, MkAtomTerm(Yap_LookupAtom(Yap_ROOTDIR)));
setAtomicGlobalPrologFlag(HOME_FLAG,
MkAtomTerm(Yap_LookupAtom(Yap_ROOTDIR)));
if (Yap_PLDIR)
setAtomicGlobalPrologFlag(PROLOG_LIBRARY_DIRECTORY_FLAG,
MkAtomTerm(Yap_LookupAtom(Yap_PLDIR)));
MkAtomTerm(Yap_LookupAtom(Yap_PLDIR)));
if (Yap_DLLDIR)
setAtomicGlobalPrologFlag(PROLOG_FOREIGN_DIRECTORY_FLAG,
MkAtomTerm(Yap_LookupAtom(Yap_DLLDIR)));
MkAtomTerm(Yap_LookupAtom(Yap_DLLDIR)));
}
static void print_usage(void) {

File diff suppressed because it is too large Load Diff

View File

@ -9,8 +9,8 @@
*
* @{
*
* These classes wrap engine and query. An engine is an environment where we can rum
* Prolog, that is, where we can run queries.
* These classes wrap engine and query. An engine is an environment where we
* can rum Prolog, that is, where we can run queries.
*
* Also, supports callbacks and engine configuration.
*
@ -35,8 +35,7 @@ class X_API YAPPredicate;
* interface to a YAP Query;
* uses an SWI-like status info internally.
*/
class X_API YAPQuery : public YAPPredicate
{
class X_API YAPQuery : public YAPPredicate {
bool q_open;
int q_state;
yhandle_t q_g, q_handles;
@ -48,30 +47,29 @@ class X_API YAPQuery : public YAPPredicate
YAPPairTerm names;
YAPTerm goal;
// temporaries
Term tnames, tgoal ;
Term tnames, tgoal;
inline void setNext() { // oq = LOCAL_execution;
// LOCAL_execution = this;
q_open = true;
q_state = 0;
q_flags = true; // PL_Q_PASS_EXCEPTION;
inline void setNext() { // oq = LOCAL_execution;
// LOCAL_execution = this;
q_open = true;
q_state = 0;
q_flags = true; // PL_Q_PASS_EXCEPTION;
q_p = P;
q_cp = CP;
// make sure this is safe
q_handles = LOCAL_CurSlot;
};
q_p = P;
q_cp = CP;
// make sure this is safe
q_handles = LOCAL_CurSlot;
};
void openQuery();
void openQuery( Term *ts);
PredEntry *rewriteUndefQuery();
PredEntry *rewriteUndefQuery();
public:
YAPQuery() {
goal = TermTrue;
openQuery( nullptr);
};
YAPQuery() {
goal = TermTrue;
openQuery();
};
/// main constructor, uses a predicate and an array of terms
///
/// It is given a YAPPredicate _p_ , and an array of terms that must have at
@ -89,32 +87,40 @@ YAPQuery() {
///
/// It is given a functor, and an array of terms that must have at least
/// the same arity as the functor. Works within the current module.
//YAPQuery(YAPFunctor f, YAPTerm t[]);
// YAPQuery(YAPFunctor f, YAPTerm t[]);
/// string constructor without varnames
///
/// It is given a string, calls the parser and obtains a Prolog term that
/// should be a callable
/// goal.
inline YAPQuery(const char *s) : YAPPredicate(s, tgoal, tnames)
{
inline YAPQuery(const char *s) : YAPPredicate(s, tgoal, tnames) {
CELL *qt = nullptr;
__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "got game %d",
LOCAL_CurSlot);
if (!ap)
return;
__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "%s", names.text());
goal = YAPTerm(tgoal);
if (IsPairTerm(tgoal)) {
qt = RepPair(tgoal);
tgoal = Yap_MkApplTerm(Yap_MkFunctor(Yap_LookupAtom("consult"), 1),1,qt);
} else if (IsApplTerm(tgoal)) {
Functor f = FunctorOfTerm(tgoal);
__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "got game %d",
LOCAL_CurSlot);
if (!ap)
return;
__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "%s", names.text());
if (IsPairTerm(tgoal)) {
qt = RepPair(tgoal);
tgoal = Yap_MkApplTerm(FunctorCsult, 1, qt);
ap = RepPredProp(PredPropByFunc(FunctorCsult, TermProlog));
}
goal = YAPTerm(tgoal);
if (IsApplTerm(tgoal)) {
Functor f = FunctorOfTerm(tgoal);
if (!IsExtensionFunctor(f)) {
if (!IsExtensionFunctor(f)) {
qt = RepAppl(tgoal)+1;
arity_t arity = ap->ArityOfPE;
if (arity) {
qt = RepAppl(tgoal) + 1;
for (arity_t i = 0; i < arity; i++)
XREGS[i + 1] = qt[i];
}
}
}
names = YAPPairTerm(tnames);
openQuery(qt);
}
names = YAPPairTerm(tnames);
openQuery();
};
// inline YAPQuery() : YAPPredicate(s, tgoal, tnames)
// {
@ -135,41 +141,39 @@ YAPQuery() {
/// set flags for query execution, currently only for exception handling
void setFlag(int flag) { q_flags |= flag; }
/// reset flags for query execution, currently only for exception handling
void resetFlag(int flag) { q_flags &= ~flag; }
/// first query
///
/// actually implemented by calling the next();
inline bool first() { return next(); }
/// ask for the next solution of the current query
/// same call for every solution
bool next();
/// does this query have open choice-points?
/// or is it deterministic?
bool deterministic();
/// represent the top-goal
const char *text();
/// remove alternatives in the current search space, and finish the current
/// query
/// finish the current query: undo all bindings.
void close();
/// query variables.
void cut();
Term namedVars() {return names.term(); };
YAPPairTerm namedVarTerms() {return names; };
/// query variables, but copied out
std::vector<Term> namedVarsVector() {
return names.listToArray(); };
/// convert a ref to a binding.
YAPTerm getTerm(yhandle_t t);
/// simple YAP Query;
/// just calls YAP and reports success or failure, Useful when we just
/// want things done, eg YAPCommand("load_files(library(lists), )")
inline bool command()
{
bool rc = next();
close();
return rc;
};
void resetFlag(int flag) { q_flags &= ~flag; }
/// first query
///
/// actually implemented by calling the next();
inline bool first() { return next(); }
/// ask for the next solution of the current query
/// same call for every solution
bool next();
/// does this query have open choice-points?
/// or is it deterministic?
bool deterministic();
/// represent the top-goal
const char *text();
/// remove alternatives in the current search space, and finish the current
/// query
/// finish the current query: undo all bindings.
void close();
/// query variables.
void cut();
Term namedVars() { return names.term(); };
YAPPairTerm namedVarTerms() { return names; };
/// query variables, but copied out
std::vector<Term> namedVarsVector() { return names.listToArray(); };
/// convert a ref to a binding.
YAPTerm getTerm(yhandle_t t);
/// simple YAP Query;
/// just calls YAP and reports success or failure, Useful when we just
/// want things done, eg YAPCommand("load_files(library(lists), )")
inline bool command() {
bool rc = next();
close();
return rc;
};
};
// Java support
@ -177,8 +181,7 @@ inline bool command()
/// This class implements a callback Prolog-side. It will be inherited by the
/// Java or Python
/// class that actually implements the callback.
class X_API YAPCallback
{
class X_API YAPCallback {
public:
virtual ~YAPCallback() {}
virtual void run() { LOG("callback"); }
@ -186,187 +189,105 @@ public:
};
/// @brief Setup all arguments to a new engine
struct X_API YAPEngineArgs: YAP_init_args {
struct X_API YAPEngineArgs : YAP_init_args {
public:
YAPEngineArgs():yap_boot_params() {
char s[32];
strcpy(s, "startup.yss" );
Yap_InitDefaults(this,s,0,nullptr);
YAPEngineArgs() : yap_boot_params() {
char s[32];
strcpy(s, "startup.yss");
Yap_InitDefaults(this, s, 0, nullptr);
#if YAP_PYTHON
Embedded = true;
Embedded = true;
python_in_python = Py_IsInitialized();
#endif
};
inline void setEmbedded( bool fl )
{
Embedded = fl;
};
inline bool getEmbedded( )
{
return Embedded;
};
inline void setEmbedded(bool fl) { Embedded = fl; };
inline void setStackSize( bool fl )
{
StackSize = fl;
};
inline bool getEmbedded() { return Embedded; };
inline bool getStackSize( )
{
return StackSize;
};
inline void setStackSize(bool fl) { StackSize = fl; };
inline void setTrailSize( bool fl )
{
TrailSize = fl;
};
inline bool getStackSize() { return StackSize; };
inline bool getTrailSize( )
{
return TrailSize;
};
inline void setTrailSize(bool fl) { TrailSize = fl; };
inline bool getMStackSize( )
{
return StackSize;
};
inline bool getTrailSize() { return TrailSize; };
inline void setMaxTrailSize( bool fl )
{
MaxTrailSize = fl;
};
inline bool getMStackSize() { return StackSize; };
inline bool getMaxTrailSize( )
{
return MaxTrailSize;
};
inline void setMaxTrailSize(bool fl) { MaxTrailSize = fl; };
inline void setYapLibDir( const char * fl )
{
YapLibDir = (const char *)malloc(strlen(fl)+1);
inline bool getMaxTrailSize() { return MaxTrailSize; };
inline void setYapLibDir(const char *fl) {
YapLibDir = (const char *)malloc(strlen(fl) + 1);
strcpy((char *)YapLibDir, fl);
};
inline const char * getYapLibDir( )
{
return YapLibDir;
};
inline const char *getYapLibDir() { return YapLibDir; };
inline void setYapShareDir( const char * fl )
{
YapShareDir = (const char *)malloc(strlen(fl)+1);
inline void setYapShareDir(const char *fl) {
YapShareDir = (const char *)malloc(strlen(fl) + 1);
strcpy((char *)YapShareDir, fl);
};
inline const char * getYapShareDir( )
{
return YapShareDir;
};
inline const char *getYapShareDir() { return YapShareDir; };
inline void setSavedState( const char * fl )
{
SavedState = (const char *)malloc(strlen(fl)+1);
inline void setSavedState(const char *fl) {
SavedState = (const char *)malloc(strlen(fl) + 1);
strcpy((char *)SavedState, fl);
};
inline const char * getSavedState( )
{
return SavedState;
};
inline const char *getSavedState() { return SavedState; };
inline void setYapPrologBootFile( const char * fl )
{
YapPrologBootFile = (const char *)malloc(strlen(fl)+1);
inline void setYapPrologBootFile(const char *fl) {
YapPrologBootFile = (const char *)malloc(strlen(fl) + 1);
strcpy((char *)YapPrologBootFile, fl);
};
inline const char * getYapPrologBootFile( )
{
return YapPrologBootFile;
};
inline void setYapPrologGoal( const char * fl )
{
YapPrologGoal = fl;
};
inline const char *getYapPrologBootFile() { return YapPrologBootFile; };
inline const char * getYapPrologGoal( )
{
return YapPrologGoal;
};
inline void setYapPrologGoal(const char *fl) { YapPrologGoal = fl; };
inline void setYapPrologTopLevelGoal( const char * fl )
{
inline const char *getYapPrologGoal() { return YapPrologGoal; };
inline void setYapPrologTopLevelGoal(const char *fl) {
YapPrologTopLevelGoal = fl;
};
inline const char * getYapPrologTopLevelGoal( )
{
inline const char *getYapPrologTopLevelGoal() {
return YapPrologTopLevelGoal;
};
inline void setHaltAfterConsult( bool fl )
{
HaltAfterConsult = fl;
};
inline void setHaltAfterConsult(bool fl) { HaltAfterConsult = fl; };
inline bool getHaltAfterConsult( )
{
return HaltAfterConsult;
};
inline bool getHaltAfterConsult() { return HaltAfterConsult; };
inline void setFastBoot( bool fl )
{
FastBoot = fl;
};
inline void setFastBoot(bool fl) { FastBoot = fl; };
inline bool getFastBoot( )
{
return FastBoot;
};
inline bool getFastBoot() { return FastBoot; };
#if __ANDROID__
//> export ResoourceManager
inline void setAssetManager( AAssetManager *mgr )
{
assetManager = mgr;
};
//> export ResoourceManager
inline void setAssetManager(AAssetManager *mgr) { assetManager = mgr; };
#endif
inline void setArgc( int fl )
{
Argc = fl;
};
inline void setArgc(int fl) { Argc = fl; };
inline int getArgc( )
{
return Argc;
};
inline int getArgc() { return Argc; };
inline void setArgv( char ** fl )
{
Argv = fl;
};
inline char ** getArgv( )
{
return Argv;
};
inline void setArgv(char **fl) { Argv = fl; };
inline char **getArgv() { return Argv; };
};
/**
* @brief YAP Engine: takes care of the execution environment
where we can go executing goals.
*
*
*/
class YAPEngine
{
class YAPEngine {
private:
YAPEngineArgs *engine_args;
YAPCallback *_callback;
@ -375,32 +296,29 @@ private:
YAP_dogoalinfo q;
PredEntry *rewriteUndefEngineQuery(PredEntry *ap, Term t, Term tmod);
public :
/// construct a new engine; may use a variable number of arguments
YAPEngine(YAPEngineArgs *cargs)
{
public:
/// construct a new engine; may use a variable number of arguments
YAPEngine(YAPEngineArgs *cargs) {
engine_args = cargs;
//doInit(cargs->boot_file_type);
// doInit(cargs->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(); };
/// remove current callback
void delYAPCallback() { _callback = 0; };
/// set a new callback
void setYAPCallback(YAPCallback *cb)
{
void setYAPCallback(YAPCallback *cb) {
delYAPCallback();
_callback = cb;
};
/// execute the callback.
////void run() { if (_callback) _callback.run(); }
/// execute the callback with a text argument.
void run(char *s)
{
void run(char *s) {
if (_callback)
_callback->run(s);
}
@ -427,25 +345,20 @@ private:
bool mgoal(Term t, Term tmod);
/// current directory for the engine
bool goal(Term t)
{
return mgoal(t, CurrentModule);
}
bool goal(Term t) { return mgoal(t, CurrentModule); }
/// reset Prolog state
void reSet();
/// assune that there are no stack pointers, just release memory
// for last execution
void release();
const char *currentDir()
{
const char *currentDir() {
char dir[1024];
std::string s = Yap_getcwd(dir, 1024 - 1);
return s.c_str();
};
/// report YAP version as a string
const char *version()
{
const char *version() {
std::string s = Yap_version();
return s.c_str();
};
@ -457,16 +370,15 @@ private:
Term fun(YAPTerm t) { return fun(t.term()); };
//> 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())));
bool setStringFlag(std::string arg, std::string path) {
return setYapFlag(MkAtomTerm(Yap_LookupAtom(arg.data())),
MkAtomTerm(Yap_LookupAtom(path.data())));
};
Term top_level( std::string s);
Term next_answer(YAPQuery * &Q);
};
Term top_level(std::string s);
Term next_answer(YAPQuery *&Q);
};
#endif /* YAPQ_HH */
/// @}
/// @}

View File

@ -170,9 +170,9 @@ open_mem_read_stream(USES_REGS1) /* $open_mem_read_stream(+List,-Stream) */
if (!buf) {
return false;
}
buf = pop_output_text_stack(l, buf);
sno = Yap_open_buf_read_stream(buf, strlen(buf) + 1, &LOCAL_encoding,
MEM_BUF_MALLOC);
pop_text_stack(l);
t = Yap_MkStream(sno);
return Yap_unify(ARG2, t);
}
@ -292,16 +292,16 @@ void Yap_MemOps(StreamDesc *st) {
st->stream_getc = PlGetc;
}
bool Yap_CloseMemoryStream(int sno) {
if ((GLOBAL_Stream[sno].status & Output_Stream_f) && GLOBAL_Stream[sno].file) {
if ((GLOBAL_Stream[sno].status & Output_Stream_f) &&
GLOBAL_Stream[sno].file) {
fflush(GLOBAL_Stream[sno].file);
fclose(GLOBAL_Stream[sno].file);
if (GLOBAL_Stream[sno].status & FreeOnClose_Stream_f)
free(GLOBAL_Stream[sno].nbuf);
} else {
if (GLOBAL_Stream[sno].file)
fclose(GLOBAL_Stream[sno].file);
fclose(GLOBAL_Stream[sno].file);
if (GLOBAL_Stream[sno].status & FreeOnClose_Stream_f)
free(GLOBAL_Stream[sno].nbuf);
}

View File

@ -1,6 +1,5 @@
#include "py4yap.h"
#include <VFS.h>
@ -27,7 +26,8 @@ PyObject *py_ModDict;
VFS_t pystream;
static void *py_open(VFS_t *me, int sno, const char *name, const char *io_mode) {
static void *py_open(VFS_t *me, int sno, const char *name,
const char *io_mode) {
#if HAVE_STRCASESTR
if (strcasestr(name, "//python/") == name)
name += strlen("//python/");
@ -35,56 +35,57 @@ static void *py_open(VFS_t *me, int sno, const char *name, const char *io_mode)
if (strstr(name, "//python/") == name)
name += strlen("//python/");
#endif
StreamDesc *st = YAP_RepStreamFromId(sno);
StreamDesc *st = YAP_RepStreamFromId(sno);
// we assume object is already open, so there is no need to open it.
PyObject *stream = string_to_python(name, true, NULL);
if (stream == Py_None)
return NULL;
Py_INCREF(stream);
st->u.private_data = stream;
st->vfs = me;
st->status = Append_Stream_f | Output_Stream_f;
Yap_DefaultStreamOps(st);
return stream;
Py_INCREF(stream);
st->u.private_data = stream;
st->vfs = me;
st->status = Append_Stream_f | Output_Stream_f;
Yap_DefaultStreamOps(st);
return stream;
}
static bool py_close(int sno) {
return true;
StreamDesc *s = YAP_GetStreamFromId(sno);
StreamDesc *s = YAP_GetStreamFromId(sno);
PyObject *fclose = PyObject_GetAttrString(s->u.private_data, "close");
PyObject *rc = PyObject_CallObject(fclose, NULL);
bool v = (rc == Py_True);
return v;
}
static int py_put(int sno, int ch) {
// PyObject *pyw; // buffer
//int pyw_kind;
//PyObject *pyw_data;
// int pyw_kind;
// PyObject *pyw_data;
char s[2];
StreamDesc *st = YAP_GetStreamFromId(sno);
// PyUnicode_WRITE(pyw_kind, pyw_data, 0, ch);
PyObject *err,*fput = PyObject_GetAttrString(st->u.private_data, "write");
char s[2];
StreamDesc *st = YAP_GetStreamFromId(sno);
// PyUnicode_WRITE(pyw_kind, pyw_data, 0, ch);
PyObject *err, *fput = PyObject_GetAttrString(st->u.private_data, "write");
s[0] = ch;
s[1] = '\0';
PyObject_CallFunctionObjArgs(fput, PyUnicode_FromString(s), NULL);
if ((err = PyErr_Occurred())) {
PyErr_SetString(err, "Error in put\n");// %s:%s:%d!\n", __FILE__, __FUNCTION__, __LINE__);
}
s[1] = '\0';
PyObject_CallFunctionObjArgs(fput, PyBytes_FromString(s), NULL);
if ((err = PyErr_Occurred())) {
PyErr_SetString(
err,
"Error in put\n"); // %s:%s:%d!\n", __FILE__, __FUNCTION__, __LINE__);
}
return ch;
}
static int py_get(int sno) {
StreamDesc *s = YAP_GetStreamFromId(sno);
StreamDesc *s = YAP_GetStreamFromId(sno);
PyObject *fget = PyObject_GetAttrString(s->u.private_data, "read");
PyObject *pyr = PyObject_CallFunctionObjArgs(fget, PyLong_FromLong(1), NULL);
return PyUnicode_READ_CHAR(pyr, 0);
}
static int64_t py_seek(int sno, int64_t where, int how) {
StreamDesc *s = YAP_GetStreamFromId(sno);
StreamDesc *s = YAP_GetStreamFromId(sno);
PyObject *fseek = PyObject_GetAttrString(s->u.private_data, "seek");
PyObject *pyr = PyObject_CallFunctionObjArgs(fseek, PyLong_FromLong(where),
PyLong_FromLong(how), NULL);
@ -92,7 +93,7 @@ static int64_t py_seek(int sno, int64_t where, int how) {
}
static void py_flush(int sno) {
StreamDesc *s = YAP_GetStreamFromId(sno);
StreamDesc *s = YAP_GetStreamFromId(sno);
PyObject *flush = PyObject_GetAttrString(s->u.private_data, "flush");
PyObject_CallFunction(flush, NULL);
}
@ -111,9 +112,9 @@ static void python_output(void) {
#endif
static bool init_python_stream(void) {
//pyw = PyUnicode_FromString("x");
//pyw_kind = PyUnicode_KIND(pyw);
//pyw_data = PyUnicode_DATA(pyw);
// pyw = PyUnicode_FromString("x");
// pyw_kind = PyUnicode_KIND(pyw);
// pyw_data = PyUnicode_DATA(pyw);
pystream.name = "python stream";
pystream.vflags =
@ -227,6 +228,6 @@ X_API bool do_init_python(void) {
install_pl2pl();
// PyGILState_Release(gstate);
add_modules();
// python_output();
// python_output();
return true;
}

View File

@ -61,13 +61,13 @@ argi(N,I,I1) :-
I1 is I+1.
python_query( Self, String ) :-
yap_flag(typein_module, Mod),
atomic_to_term( String, Goal, VarNames ),
query_to_answer( Mod:Goal, VarNames, Status, Bindings),
maplist(in_dict(Self.bindings), Bindings),
query_to_answer( Goal, VarNames, Status, Bindings),
Self.port := Status,
write_query_answer( Bindings ),
nl( user_error ),
Self.port := Status.
nl(user_error),
Self.bindings := {},
maplist(in_dict(Self.bindings), Bindings).
in_dict(Dict, var([V0,V|Vs])) :- !,
Dict[V] := V0,

View File

@ -1,6 +1,7 @@
import os
import sys
import abc
import math
import yap4py.yapi
from IPython.core import interactiveshell
@ -14,6 +15,7 @@ from pygments import highlight
from pygments.lexers.prolog import PrologLexer
from pygments.formatters import HtmlFormatter
import pdb
from collections import namedtuple
@ -87,7 +89,7 @@ class YAPCompleter:
class YAPInteractive(InteractiveShell):
"""An enhanced, interactive shell for YAP."""
def init_yap_completer(self):
"""Initialize the completion machinery.
@ -110,9 +112,9 @@ class YAPInteractive(InteractiveShell):
self.yapeng.goal(use_module(library("jupyter")))
self.q = None
self.run = False
self.os = ""
self.port = None
self.init_yap_completer()
self.init_syntax_highlighting()
def init_syntax_highlighting(self, changes=None):
# Python source parser/formatter for syntax highlighting
@ -169,7 +171,7 @@ class YAPInteractive(InteractiveShell):
def run_cell(self, raw_cell, store_history=True, silent=False,
shell_futures=True):
"""Run a complete IPython cell.
@ -206,9 +208,9 @@ class YAPInteractive(InteractiveShell):
# vs is the list of variables
# you can print it out, the left-side is the variable name,
# the right side wraps a handle to a variable
# pdb.set_trace()
# #pdb.set_trace()
# atom match either symbols, or if no symbol exists, strings, In this case
pdb.set_trace()
# import pdb; pdb.set_trace()
# atom match either symbols, or if no symbol ex b pl nvists, strings, In this case
# variable names should match strings
# ask = True
# launch the query
@ -222,6 +224,7 @@ class YAPInteractive(InteractiveShell):
store_history = False
if store_history:
self.execution_count = self.execution_count+1
result.execution_count = self.execution_count
def error_before_exec(value):
@ -237,13 +240,14 @@ class YAPInteractive(InteractiveShell):
# prefilter_manager) raises an exception, we store it in this variable
# so that we can display the error after logging the input and storing
# it in the history.
# preprocessing_exc_tuple = None
# try:
# # Static input transformations
# cell = raw_cell #self.input_transformer_manager.transform_cell(raw_cell)
# except SyntaxError:
# preprocessing_exc_tuple = sys.exc_info()
cell = raw_cell # cell has to exist so it can be stored/logged
preprocessing_exc_tuple = None
try:
# Static input transformations
cell = raw_cell.strip(" \n\t").rstrip(" \n\t") #self.input_transformer_manager.transform_cell(raw_cell.strip(" \n\t").rstrip(" \n\t"))
except SyntaxError:
preprocessing_exc_tuple = sys.exc_info()
#
# cell = raw_cell # cell has to exist so it can be stored/logged
# else:
# # import pdb; pdb.set_trace()
# if False and len(cell.splitlines()) == 1:
@ -277,6 +281,8 @@ class YAPInteractive(InteractiveShell):
# compiler
# compiler = self.compile if shell_futures else CachingCompiler()
pdb.set_trace()
cell_name = str( self.execution_count)
if cell[0] == '%':
@ -308,7 +314,7 @@ class YAPInteractive(InteractiveShell):
has_raised = False
try:
self.bindings = dict = {}
state = self.jupyter_query(cell)
state = self.jupyter_query(raw_cell)
if state:
self.last_execution_succeeded = True
result.result = (True, dict)
@ -341,7 +347,7 @@ class YAPInteractive(InteractiveShell):
def prolog_cell(self,s):
""""
Trasform a text into program+query. A query is the
last line if the last line is non-empty and does not terminate
last line if the last line is non-empty and does not terminate
on a dot. You can also finish with
- `*`: you request all solutions
@ -349,33 +355,48 @@ class YAPInteractive(InteractiveShell):
- '?'[N]: you want an answer; optionally you want N answers
If the line terminates on a `*/` or starts on a `%` we assume the line
is a comment.
is a comment.
"""
s = s.rstrip()
take = 0
its = 0
[program,x,query] = s.partition('\n')
if query == '':
query = program
while take < len(query):
take += 1
ch = query[-take]
if ch.isdigit():
its = its + ord(ch) - ord('0')
elif ch == '*' and take == 1:
return program, query[:-take], -1
elif ch == '.' and take == 1:
return s, '', 1
elif ch == '/' and query[-2] == '*' and take == 1:
return program, query[:-take], -1
elif ch == '^' and take == 1:
return program, query[:-take], 1
elif ch == '?':
return program, query[:-take], its+1
s = s.rstrip().strip()
l = s.split("\n")
while not l[0]:
l = l[1:]
rl = []
for h in l:
if h and h[0] == '%':
if h[1] == '%':
break
else:
return program, query, 1
return s, '', 1
rl = [h] + rl
if not rl:
return '','',1
query = rl[0]
program = ''
i=0
for h in rl:
if h and not h.isspace():
break
i += 1
rl = rl[i:]
if not rl:
return '','',1
take = 1
ch = query[-take]
if ch == '*' and take == 1:
query = l[:-1]
sols = -1
if ch == '.':
return s, '', 1
rl = rl[1:]
while True:
h = rl[0]
if h and not h.isspace():
query = h + '\n'+ query
rl = rl[1:]
break
for l in rl:
program = l + '\n'+ program
return program,query,take
def jupyter_query(self, s):
# import pdb; pdb.set_trace()
@ -383,15 +404,19 @@ class YAPInteractive(InteractiveShell):
# construct a self.query from a one-line string
# self.q is opaque to Python
self.bindings = {}
self.port = "call"
iterations=1
if self.q and s != self.os:
self.q.close()
self.q = None
if not self.q:
import pdb; pdb.set_trace()
program,query,self.iterations = self.prolog_cell(s)
#import pdb; pdb.set_trace()
self.port = "call"
program,query,iterations = self.prolog_cell(s)
self.q = self.yapeng.query(jupyter_query(self, program, query))
self.os = s
self.solutions = []
if not self.q:
return True, []
self.os = s
# vs is the list of variables
# you can print it out, the left-side is the variable name,
# the right side wraps a handle to a variable
@ -406,23 +431,34 @@ class YAPInteractive(InteractiveShell):
# ask = True
# launch the query
# run the new commbnand using the given tracer
solutions = []
while self.iterations > 0:
self.iterations -= 1
rc = self.answer(self.q)
if rc:
# deterministic = one solution
if self.port == "exit":
# done
self.q.close()
self.q = None
self.os = ""
print("yes")
solutions += [self.bindings]
if iterations <0:
while self.answer( self.q):
self.solutions += [self.bindings]
self.q.close()
self.q = None
self.os = ""
if not self.solutions:
print("no solutions found")
return True
rc = self.answer(self.q)
if rc:
# deterministic = one solution
#Dict = {}
#engine.goal(show_answer( q.namedVars(), Dict))
self.solutions += [self.bindings]
if self.port == "exit":
# done
self.q.close()
self.q = None
self.os = ""
return True
else:
print("No (more) answers")
self.q.close()
self.q = None
return True, solutions
self.os = ''
return False
def answer(self, q):
try:
@ -430,7 +466,7 @@ class YAPInteractive(InteractiveShell):
except Exception as e:
print(e.args[1])
self.yapeng.goal(exit_cell(self))
return False, None
return e
class YAPInteractiveABC(metaclass=abc.ABCMeta):

View File

@ -1,4 +1,14 @@
/**
* @file jupyter.yap
*
* @brief allow interaction between Jupyter and YAP.
*
* @long The code in here:
* - establishes communication between Prolog and Python Streams
* - inputs Prolog code and queries
* - supports completion of Prolog programs.
* -
*/
:- use_module(library(yapi)).
:- use_module(library(lists)).
:- use_module(library(maplist)).
@ -6,33 +16,50 @@
:- python_import(sys).
:- start_low_level_trace.
user:jupyter_query(Self, Cell, Line ) :-
setup_call_cleanup(
enter_cell(Self),
jupyter_cell(Self, Cell, Line),
exit_cell(Self) ).
exit_cell(Self)
).
jupyter_cell(_Self, Cell, _) :-
open_mem_read_stream( Cell, Stream),
load_files(['jupyter cell'],[stream(Stream)]),
close( Stream ),
stop_low_level_trace,
jupyter_consult(Cell),
fail.
jupyter_cell( _Self, _, Line ) :-
blank( Line ),
!.
jupyter_cell( Self, _, Line ) :-
start_low_level_trace,
python_query( Self, Line ).
jupyter_consult(Text) :-
blank( Text ),
!.
jupyter_consult(Cell) :-
open_mem_read_stream( Cell, Stream),
load_files(user:'jupyter cell',[stream(Stream)]).
%should load_files close?
blank(Text) :-
atom_codes(Text, L),
maplist( blankc, L).
blankc(' ').
blankc('\n').
blankc('\t').
enter_cell(_Self) :-
%open('//python/sys.stdin', read, _Input, []),
open('//python/sys.stdout', append, _Output, []),
open('//python/sys.stdout', append, _Error, []),
%set_prolog_flag(user_input, _Input),
set_prolog_flag(user_output, _Output),
set_prolog_flag(user_error, _Error),
writeln(hello),
format(user_error,'h~n',[]),
:= print("py"),
:= sys.stderr.write("ok\n").
set_prolog_flag(user_error, _Error).
exit_cell(_Self) :-
%close( user_input),
close( user_output),
close( user_error).

View File

@ -244,10 +244,11 @@ load_files(Files,Opts) :-
'$lf_option'('$parent_topts', 28, _).
'$lf_option'(must_be_module, 29, false).
'$lf_option'('$source_pos', 30, _).
'$lf_option'(initialization, 31, Ref) :-
'$lf_option'('$from_stream', 31, false).
'$lf_option'(initialization, 32, Ref) :-
nb:nb_queue(Ref).
'$lf_option'(last_opt, 31).
'$lf_option'(last_opt, 32).
'$lf_opt'( Op, TOpts, Val) :-
'$lf_option'(Op, Id, _),
@ -265,8 +266,7 @@ load_files(Files,Opts) :-
functor( OldTOpts, opt, LastOpt ),
'$lf_opt'('$context_module', OldTOpts, user)
),
'$check_files'(Files,load_files(Files,Opts)),
'$lf_option'(last_opt, LastOpt),
'$lf_option'(last_opt, LastOpt),
functor( TOpts, opt, LastOpt ),
( source_location(ParentF, Line) -> true ; ParentF = user_input, Line = -1 ),
'$lf_opt'('$location', TOpts, ParentF:Line),
@ -276,16 +276,22 @@ load_files(Files,Opts) :-
'$lf_opt'('$parent_topts', TOpts, OldTOpts),
'$process_lf_opts'(Opts,TOpts,Files,Call),
'$lf_default_opts'(1, LastOpt, TOpts),
'$lf_opt'(stream, TOpts, Stream),
( nonvar(Stream) ->
'$set_lf_opt'('$from_stream', TOpts, true )
;
'$check_files'(Files,load_files(Files,Opts))
),
'$check_use_module'(Call,UseModule),
'$lf_opt'('$use_module', TOpts, UseModule),
'$current_module'(M0),
( '$lf_opt'(autoload, TOpts, Autoload),
var(Autoload) ->
Autoload = OldAutoload
;
true
),
% make sure we can run consult
( '$lf_opt'(autoload, TOpts, Autoload),
var(Autoload) ->
Autoload = OldAutoload
;
true
),
% make sure we can run consult
'$init_consult',
'$lf'(Files, M0, Call, TOpts).
@ -432,7 +438,7 @@ load_files(Files,Opts) :-
'$lf'(File, Mod, Call, TOpts) :-
'$lf_opt'(stream, TOpts, Stream),
b_setval('$user_source_file', File),
( var(Stream) ->
( '$lf_opt'('$from_stream', TOpts, false ) ->
/* need_to_open_file */
( '$full_filename'(File, Y) -> true ; '$do_error'(existence_error(source_sink,File),Call) ),
( open(Y, read, Stream) -> true ; '$do_error'(permission_error(input,stream,Y),Call) )
@ -448,18 +454,22 @@ load_files(Files,Opts) :-
'$start_lf'(If, Mod, Stream, TOpts, File, Y, Reexport, Imports),
close(Stream).
% consulting from a stre
'$start_lf'(_not_loaded, Mod, Stream, TOpts, UserFile, File, _Reexport, _Imports) :-
'$lf_opt'('$from_stream', TOpts, true ),
!,
'$do_lf'(Mod, Stream, UserFile, File, TOpts).
'$start_lf'(not_loaded, Mod, _Stream, TOpts, UserFile, File, Reexport,Imports) :-
'$file_loaded'(File, Mod, Imports, TOpts), !,
'$lf_opt'('$options', TOpts, Opts),
'$lf_opt'('$location', TOpts, ParentF:Line),
'$loaded'(File, UserFile, Mod, ParentF, Line, not_loaded, _, _Dir, Opts),
'$loaded'(File, UserFile, Mod, ParentF, Line, not_loaded, _, _Dir, TOpts, Opts),
'$reexport'( TOpts, ParentF, Reexport, Imports, File ).
'$start_lf'(changed, Mod, _Stream, TOpts, UserFile, File, Reexport, Imports) :-
'$file_unchanged'(File, Mod, Imports, TOpts), !,
'$lf_opt'('$options', TOpts, Opts),
'$lf_opt'('$location', TOpts, ParentF:Line),
'$loaded'(File, UserFile, Mod, ParentF, Line, changed, _, _Dir, Opts),
'$loaded'(File, UserFile, Mod, ParentF, Line, changed, _, _Dir, TOpts, Opts),
'$reexport'( TOpts, ParentF, Reexport, Imports, File ).
'$start_lf'(_, Mod, PlStream, TOpts, _UserFile, File, Reexport, ImportList) :-
% check if there is a qly file
@ -677,7 +687,7 @@ db_files(Fs) :-
'$lf_opt'(consult, TOpts, Reconsult0),
'$lf_opt'('$options', TOpts, Opts),
'$lf_opt'('$location', TOpts, ParentF:Line),
'$loaded'(File, UserFile, SourceModule, ParentF, Line, Reconsult0, Reconsult, Dir, Opts),
'$loaded'(File, UserFile, SourceModule, ParentF, Line, Reconsult0, Reconsult, Dir, TOpts, Opts),
working_directory(OldD, Dir),
H0 is heapused, '$cputime'(T0,_),
current_prolog_flag(generate_debug_info, GenerateDebug),
@ -740,6 +750,7 @@ db_files(Fs) :-
'$q_do_save_file'(File, UserF, TOpts ) :-
'$lf_opt'(qcompile, TOpts, QComp),
'$lf_opt'('$source_pos', TOpts, Pos),
'$lf_opt'('$from_stream', TOpts, false),
( QComp == auto ; QComp == large, Pos > 100*1024),
'$absolute_file_name'(UserF,[file_type(qly),solutions(first),expand(true)],F),
!,
@ -844,7 +855,7 @@ nb_setval('$if_le1vel',0).
working_directory(Dir0, Dir),
'$lf_opt'(encoding, TOpts, Encoding),
set_stream(Stream, [encoding(Encoding),alias(loop_stream)] ),
'$loaded'(Y, X, Mod, _OldY, _L, include, _, Dir, []),
'$loaded'(Y, X, Mod, _OldY, _L, include, _, Dir, TOpts,[]),
( nb:'$nb_getval'('$included_file', OY, fail ) -> true ; OY = [] ),
nb_setval('$included_file', Y),
print_message(informational, loading(including, Y)),
@ -1012,10 +1023,9 @@ prolog_load_context(stream, Stream) :-
time_file64(F,CurrentAge),
( (Age == CurrentAge ; Age = -1) -> true; erase(R), fail).
% inform the file has been loaded and is now available.
'$loaded'(F, UserFile, M, OldF, Line, Reconsult0, Reconsult, Dir, Opts) :-
( F == user_input -> working_directory(Dir,Dir) ; file_directory_name(F, Dir) ),
'$loaded'(F, UserFile, M, OldF, Line, Reconsult0, Reconsult, Dir, TOpts, Opts) :-
( '$lf_opt'('$from_stream',TOpts,true) -> working_directory(Dir,Dir) ; file_directory_name(F, Dir) ),
nb_setval('$consulting_file', F ),
(
% if we are reconsulting, always start from scratch
@ -1044,7 +1054,7 @@ prolog_load_context(stream, Stream) :-
;
Reconsult = Reconsult0
),
( F == user_input -> Age = 0 ; time_file64(F, Age) ),
( '$lf_opt'('$from_stream',TOpts,true) -> Age = 0 ; time_file64(F, Age) ),
% modules are logically loaded only once
( recorded('$module','$module'(F,_DonorM,_SourceF, _AllExports, _Line),_) -> true ;

View File

@ -348,7 +348,6 @@ If this hook predicate succeeds it must instantiate the _Action_ argument to th
:- dynamic user:exception/3.
:- reconsult('pathconf.yap').
/*
Add some tests