trying to improve Python interface

This commit is contained in:
Vitor Santos Costa
2016-12-10 01:01:10 -06:00
parent 474fa2fe14
commit 70b11ab8f9
35 changed files with 592 additions and 19841 deletions

View File

@@ -5,13 +5,11 @@ if (PYTHONLIBS_FOUND)
include(FindPythonModule)
set (PYTHON_SOURCES
python.c pl2py.c pybips.c py2pl.c pl2pl.c pypreds.c )
include("${CMAKE_SOURCE_DIR}/packages/python/Sources.cmake")
add_library (YAPPython SHARED ${PYTHON_SOURCES})
set (PYTHON_HEADERS
python.h)
target_link_libraries(YAPPython libYap ${PYTHON_LIBRARIES})

View File

@@ -3,7 +3,7 @@
#include "python.h"
PyObject *yap_to_python(YAP_Term t, bool eval) {
term_t yt = PL_new_term_ref();
term_t yt = YAP_InitSlot(t);
PyObject *o = term_to_python(yt, eval);
PL_reset_term_refs(yt);
return o;
@@ -18,23 +18,14 @@ PyObject *yap_to_python(YAP_Term t, bool eval) {
* @return a Python object descriptor or NULL if failed
*/
PyObject *term_to_python(term_t t, bool eval) {
// Yap_DebugPlWrite(YAP_GetFromSlot(t)); fprintf(stderr, " here I
// Yap_DebugPlWritep(YAP_GetFromSlot(t)); fprintf(stderr, " here I
YAP_Term yt = YAP_GetFromSlot(t);
switch (PL_term_type(t)) {
case PL_VARIABLE: {
PyObject *o = NULL, *pArgs;
if (eval)
return NULL;
if (PyObject_HasAttrString(py_Main, "V"))
o = PyObject_GetAttrString(py_Main, "V");
if (!o && PyObject_HasAttrString(py_Yapex, "V"))
o = PyObject_GetAttrString(py_Yapex, "V");
if (!o || !PyCallable_Check(o)) {
return NULL;
}
pArgs = PyTuple_New(1);
PyTuple_SET_ITEM(pArgs, 0, PyLong_FromLong(t));
return PyObject_CallObject(o, pArgs);
YAP_Term i = YAP_MkIntTerm(t);
return term_to_nametuple(
"H", 1, YAP_InitSlot(YAP_MkApplTerm(
YAP_MkFunctor(YAP_LookupAtom("H"), 1), 1, &i)));
};
case PL_ATOM: {
YAP_Atom at = YAP_AtomOfTerm(yt);
@@ -54,8 +45,8 @@ PyObject *term_to_python(term_t t, bool eval) {
else if (strcmp(s, "{}") == 0)
o = PyDict_New();
/* return __main__,s */
else if ((o = PyRun_String(s, Py_single_input,
PyEval_GetGlobals(), PyEval_GetLocals()))) {
else if ((o = PyRun_String(s, Py_single_input, PyEval_GetGlobals(),
PyEval_GetLocals()))) {
Py_IncRef(o);
return o;
} else if (PyObject_HasAttrString(py_Main, s)) {
@@ -83,8 +74,7 @@ PyObject *term_to_python(term_t t, bool eval) {
} break;
case PL_STRING: {
char *s = NULL;
if (!PL_get_chars(t, &s,
REP_UTF8 | CVT_ATOM | CVT_STRING | BUF_MALLOC)) {
if (!PL_get_chars(t, &s, REP_UTF8 | CVT_ATOM | CVT_STRING | BUF_MALLOC)) {
return NULL;
}
#if PY_MAJOR_VERSION < 3
@@ -97,7 +87,7 @@ PyObject *term_to_python(term_t t, bool eval) {
// fprintf(stderr, "%s\n", s);
free(s);
if (pobj) {
Py_IncRef(pobj);
Py_IncRef(pobj);
}
return pobj;
}
@@ -160,7 +150,7 @@ PyObject *deref_term_to_python(term_t t) {
if (YAP_IsVarTerm(yt)) {
char s[32];
char *o = YAP_WriteBuffer(yt, s, 31, 0);
return PyUnicode_FromString(o);
return PyUnicode_FromString(o);
}
return term_to_python(t, false);
return term_to_python(t, false);
}

View File

@@ -186,7 +186,25 @@ foreign_t python_to_term(PyObject *pVal, term_t t) {
functor_t f;
const char *s;
if ((s = (Py_TYPE(pVal)->tp_name))) {
f = PL_new_functor(PL_new_atom(s), sz);
if (!strcmp(s, "H")) {
pVal = PyTuple_GetItem(pVal, 0);
if (PyLong_Check(pVal)) {
return PyLong_AsLong(pVal);
#if PY_MAJOR_VERSION < 3
} else if (PyInt_Check(pVal)) {
return PyInt_AsLong(pVal);
#endif
}
}
if (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);
}
} else
f = PL_new_functor(ATOM_t, sz);
if (!PL_unify_functor(t, f))

View File

@@ -502,197 +502,197 @@ static long get_len_of_range(long lo, long hi, long step) {
}
#if PY_MAJOR_VERSION >= 3
static PyStructSequence_Field pnull[] = {
{"A1", NULL}, {"A2", NULL}, {"A3", NULL}, {"A4", NULL},
{"A5", NULL}, {"A6", NULL}, {"A7", NULL}, {"A8", NULL},
{"A9", NULL}, {"A9", NULL}, {"A10", NULL}, {"A11", NULL},
{"A12", NULL}, {"A13", NULL}, {"A14", NULL}, {"A15", NULL},
{"A16", NULL}, {"A17", NULL}, {"A18", NULL}, {"A19", NULL},
{"A19", NULL}, {"A20", NULL}, {"A21", NULL}, {"A22", NULL},
{"A23", NULL}, {"A24", NULL}, {"A25", NULL}, {"A26", NULL},
{"A27", NULL}, {"A28", NULL}, {"A29", NULL}, {"A29", NULL},
{"A30", NULL}, {"A31", NULL}, {"A32", NULL}, {0}};
static PyStructSequence_Field pnull[] = {
{"A1", NULL}, {"A2", NULL}, {"A3", NULL}, {"A4", NULL},
{"A5", NULL}, {"A6", NULL}, {"A7", NULL}, {"A8", NULL},
{"A9", NULL}, {"A9", NULL}, {"A10", NULL}, {"A11", NULL},
{"A12", NULL}, {"A13", NULL}, {"A14", NULL}, {"A15", NULL},
{"A16", NULL}, {"A17", NULL}, {"A18", NULL}, {"A19", NULL},
{"A19", NULL}, {"A20", NULL}, {"A21", NULL}, {"A22", NULL},
{"A23", NULL}, {"A24", NULL}, {"A25", NULL}, {"A26", NULL},
{"A27", NULL}, {"A28", NULL}, {"A29", NULL}, {"A29", NULL},
{"A30", NULL}, {"A31", NULL}, {"A32", NULL}, {0}};
static PyObject *
structseq_str(PyObject *iobj)
{
static PyObject *structseq_str(PyObject *iobj) {
/* buffer and type size were chosen well considered. */
/* buffer and type size were chosen well considered. */
#define REPR_BUFFER_SIZE 512
#define TYPE_MAXSIZE 100
PyStructSequence *obj = (PyStructSequence *)iobj;
PyTypeObject *typ = Py_TYPE(obj);
bool removelast = false;
Py_ssize_t len, i;
char buf[REPR_BUFFER_SIZE];
char *endofbuf, *pbuf = buf;
/* pointer to end of writeable buffer; safes space for "...)\0" */
endofbuf= &buf[REPR_BUFFER_SIZE-5];
PyStructSequence *obj = (PyStructSequence *)iobj;
PyTypeObject *typ = Py_TYPE(obj);
bool removelast = false;
Py_ssize_t len, i;
char buf[REPR_BUFFER_SIZE];
char *endofbuf, *pbuf = buf;
/* pointer to end of writeable buffer; safes space for "...)\0" */
endofbuf = &buf[REPR_BUFFER_SIZE - 5];
/* "typename(", limited to TYPE_MAXSIZE */
len = strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE :
strlen(typ->tp_name);
strncpy(pbuf, typ->tp_name, len);
pbuf += len;
*pbuf++ = '(';
/* "typename(", limited to TYPE_MAXSIZE */
len =
strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE : strlen(typ->tp_name);
strncpy(pbuf, typ->tp_name, len);
pbuf += len;
*pbuf++ = '(';
for (i=0; i < ((PyStructSequence *)obj)->ob_base.ob_size; i++) {
PyObject *val, *repr;
char *crepr;
for (i = 0; i < ((PyStructSequence *)obj)->ob_base.ob_size; i++) {
PyObject *val, *repr;
char *crepr;
val = PyStructSequence_GET_ITEM(obj, i);
repr = PyObject_Str(val);
if (repr == NULL)
return NULL;
crepr = PyUnicode_AsUTF8(repr);
if (crepr == NULL) {
Py_DECREF(repr);
return NULL;
}
/* + 3: keep space for ", " */
len = strlen(crepr) + 2;
if ((pbuf+len) <= endofbuf) {
strcpy(pbuf, crepr);
pbuf += strlen(crepr);
*pbuf++ = ',';
*pbuf++ = ' ';
removelast = 1;
Py_DECREF(repr);
}
else {
strcpy(pbuf, "...");
pbuf += 3;
removelast = 0;
Py_DECREF(repr);
break;
}
val = PyStructSequence_GET_ITEM(obj, i);
repr = PyObject_Str(val);
if (repr == NULL)
return NULL;
crepr = PyUnicode_AsUTF8(repr);
if (crepr == NULL) {
Py_DECREF(repr);
return NULL;
}
if (removelast) {
/* overwrite last ", " */
pbuf-=2;
}
*pbuf++ = ')';
*pbuf = '\0';
return PyUnicode_FromString(buf);
/* + 3: keep space for ", " */
len = strlen(crepr) + 2;
if ((pbuf + len) <= endofbuf) {
strcpy(pbuf, crepr);
pbuf += strlen(crepr);
*pbuf++ = ',';
*pbuf++ = ' ';
removelast = 1;
Py_DECREF(repr);
} else {
strcpy(pbuf, "...");
pbuf += 3;
removelast = 0;
Py_DECREF(repr);
break;
}
}
if (removelast) {
/* overwrite last ", " */
pbuf -= 2;
}
*pbuf++ = ')';
*pbuf = '\0';
return PyUnicode_FromString(buf);
}
static PyObject *structseq_repr(PyObject *iobj) {
static PyObject *
structseq_repr(PyObject *iobj)
{
/* buffer and type size were chosen well considered. */
/* buffer and type size were chosen well considered. */
#define REPR_BUFFER_SIZE 512
#define TYPE_MAXSIZE 100
PyStructSequence *obj = (PyStructSequence *)iobj;
PyTypeObject *typ = Py_TYPE(obj);
bool removelast = false;
Py_ssize_t len, i;
char buf[REPR_BUFFER_SIZE];
char *endofbuf, *pbuf = buf;
/* pointer to end of writeable buffer; safes space for "...)\0" */
endofbuf= &buf[REPR_BUFFER_SIZE-5];
PyStructSequence *obj = (PyStructSequence *)iobj;
PyTypeObject *typ = Py_TYPE(obj);
bool removelast = false;
Py_ssize_t len, i;
char buf[REPR_BUFFER_SIZE];
char *endofbuf, *pbuf = buf;
/* pointer to end of writeable buffer; safes space for "...)\0" */
endofbuf = &buf[REPR_BUFFER_SIZE - 5];
/* "typename(", limited to TYPE_MAXSIZE */
len = strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE :
strlen(typ->tp_name);
strncpy(pbuf, typ->tp_name, len);
pbuf += len;
*pbuf++ = '(';
/* "typename(", limited to TYPE_MAXSIZE */
len =
strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE : strlen(typ->tp_name);
strncpy(pbuf, typ->tp_name, len);
pbuf += len;
*pbuf++ = '(';
for (i=0; i < ((PyStructSequence *)obj)->ob_base.ob_size; i++) {
PyObject *val, *repr;
char *crepr;
for (i = 0; i < ((PyStructSequence *)obj)->ob_base.ob_size; i++) {
PyObject *val, *repr;
char *crepr;
val = PyStructSequence_GET_ITEM(obj, i);
repr = PyObject_Repr(val);
if (repr == NULL)
return NULL;
crepr = PyUnicode_AsUTF8(repr);
if (crepr == NULL) {
Py_DECREF(repr);
return NULL;
}
/* + 3: keep space for ", " */
len = strlen(crepr) + 2;
if ((pbuf+len) <= endofbuf) {
strcpy(pbuf, crepr);
pbuf += strlen(crepr);
*pbuf++ = ',';
*pbuf++ = ' ';
removelast = 1;
Py_DECREF(repr);
}
else {
strcpy(pbuf, "...");
pbuf += 3;
removelast = 0;
Py_DECREF(repr);
break;
}
val = PyStructSequence_GET_ITEM(obj, i);
repr = PyObject_Repr(val);
if (repr == NULL)
return NULL;
crepr = PyUnicode_AsUTF8(repr);
if (crepr == NULL) {
Py_DECREF(repr);
return NULL;
}
if (removelast) {
/* overwrite last ", " */
pbuf-=2;
}
*pbuf++ = ')';
*pbuf = '\0';
return PyUnicode_FromString(buf);
/* + 3: keep space for ", " */
len = strlen(crepr) + 2;
if ((pbuf + len) <= endofbuf) {
strcpy(pbuf, crepr);
pbuf += strlen(crepr);
*pbuf++ = ',';
*pbuf++ = ' ';
removelast = 1;
Py_DECREF(repr);
} else {
strcpy(pbuf, "...");
pbuf += 3;
removelast = 0;
Py_DECREF(repr);
break;
}
}
if (removelast) {
/* overwrite last ", " */
pbuf -= 2;
}
*pbuf++ = ')';
*pbuf = '\0';
return PyUnicode_FromString(buf);
}
#endif
static PyObject *
term_to_nametuple( const char *s, int arity, term_t t) {
PyObject *term_to_nametuple(const char *s, int arity, term_t t) {
#if PY_MAJOR_VERSION >= 3
PyTypeObject *typp;
PyObject *o;
PyObject *key = PyUnicode_FromString(s);
if (py_F2P && PyDict_Contains(py_F2P, key)) {
typp = (PyTypeObject*)PyDict_GetItem(py_F2P, key);
} else {
PyObject *o;
PyObject *key = PyUnicode_FromString(s);
if (py_F2P && PyDict_Contains(py_F2P, key)) {
typp = (PyTypeObject *)PyDict_GetItem(py_F2P, key);
} else {
typp = PyMem_Malloc(sizeof(PyTypeObject));
PyStructSequence_Desc *desc = PyMem_Malloc(sizeof(PyStructSequence_Desc));
typp = PyMem_Malloc(sizeof(PyTypeObject));
PyStructSequence_Desc *desc = PyMem_Malloc(sizeof(PyStructSequence_Desc));
desc->name = PyUnicode_AsUTF8(key);
desc->doc = "YAPTerm";
desc->fields = pnull;
desc->n_in_sequence = 32;
if (PyStructSequence_InitType2(typp, desc) < 0)
desc->name = PyUnicode_AsUTF8(key);
desc->doc = "YAPTerm";
desc->fields = pnull;
desc->n_in_sequence = 32;
if (PyStructSequence_InitType2(typp, desc) < 0)
return NULL;
typp->tp_str = structseq_str;
typp->tp_repr = structseq_repr;
// typp = PyStructSequence_NewType(desc);
Py_INCREF(typp);
// typp->tp_flags |= Py_TPFLAGS_HEAPTYPE;
PyModule_AddObject(py_Yapex, s, (PyObject *)typp);
if (py_F2P)
PyDict_SetItem(py_F2P, key, (PyObject *)typp);
}
o = PyStructSequence_New(typp);
term_t tleft = PL_new_term_ref();
int i;
for (i = 0; i < arity; i++) {
PyObject *pArg;
if (!PL_get_arg(i + 1, t, tleft))
return NULL;
pArg = term_to_python(tleft, false);
if (pArg == NULL)
return NULL;
/* pArg reference stolen here: */
PyStructSequence_SET_ITEM(o, i, pArg);
// typp = PyStructSequence_NewType(desc);
Py_INCREF(typp);
// typp->tp_flags |= Py_TPFLAGS_HEAPTYPE;
PyModule_AddObject(py_Yapex, s, (PyObject *)typp);
if (py_F2P)
PyDict_SetItem(py_F2P, key, (PyObject *)typp);
}
((PyStructSequence *)o)->ob_base.ob_size = arity;
o = PyStructSequence_New(typp);
term_t tleft = PL_new_term_ref();
int i;
return o;
}
for (i = 0; i < arity; i++) {
PyObject *pArg;
if (!PL_get_arg(i + 1, t, tleft))
return NULL;
pArg = term_to_python(tleft, false);
if (pArg == NULL)
return NULL;
/* pArg reference stolen here: */
PyStructSequence_SET_ITEM(o, i, pArg);
}
((PyStructSequence *)o)->ob_base.ob_size = arity;
return o;
#else
if (PyObject_HasAttrString(py_Yapex, "T"))
c = PyObject_GetAttrString(py_Yapex, "T");
o1 = PyTuple_New(2);
PyTuple_SET_ITEM(o1, 0, PyUnicode_FromString(s));
PyTuple_SET_ITEM(o1, 1, o);
return o1;
#endif
}
static PyObject *bip_range(term_t t) {
long ilow = 0, ihigh = 0, istep = 1;
@@ -814,8 +814,8 @@ static int copy_to_dictionary(PyObject *dict, term_t targ, term_t taux,
}
PyObject *compound_to_pytree(term_t t, functor_t fun) {
PyObject *o;
o = py_Main;
PyObject *o;
o = py_Main;
atom_t name = PL_functor_name(fun);
int arity = PL_functor_arity(fun);
@@ -845,7 +845,7 @@ PyObject *compound_to_pytree(term_t t, functor_t fun) {
} else if (fun == FUNCTOR_complex2) {
term_t targ = PL_new_term_ref();
PyObject *lhs, *rhs;
double d1 =0.0, d2=0.0;
double d1 = 0.0, d2 = 0.0;
if (!PL_get_arg(1, t, targ))
return NULL;
@@ -853,8 +853,8 @@ PyObject *compound_to_pytree(term_t t, functor_t fun) {
if (!PL_get_arg(2, t, targ))
return NULL;
rhs = term_to_python(targ, false);
if (lhs == NULL || rhs == NULL)
return NULL;
if (lhs == NULL || rhs == NULL)
return NULL;
if (PyFloat_Check(lhs)) {
d1 = PyFloat_AsDouble(lhs);
} else if (PyLong_Check(lhs)) {
@@ -935,7 +935,7 @@ PyObject *compound_to_pytree(term_t t, functor_t fun) {
term_t tleft = PL_new_term_ref();
PyObject *o = py_Main;
while (fun == FUNCTOR_dot2) {
if (!PL_get_arg(1, t, tleft))
if (!PL_get_arg(1, t, tleft))
return FALSE;
o = find_obj(o, tleft);
if (!o)
@@ -949,20 +949,17 @@ PyObject *compound_to_pytree(term_t t, functor_t fun) {
if (!arity) {
char *s;
if (!PL_get_atom_chars(t, &s) )
if (!PL_get_atom_chars(t, &s))
return NULL;
// this should never happen
return term_to_python( t, false);
// this should never happen
return term_to_python(t, false);
} else {
const char *s;
if (!(s = PL_atom_chars(name)))
return NULL;
#if PY_MAJOR_VERSION >= 3
return term_to_nametuple(s, arity, t);
#else
term_t tleft;
int i;
PyObject *c, *o1;
if (!(s = PL_atom_chars(name)))
return NULL;
term_t tleft;
int i;
PyObject *o1;
o = PyTuple_New(arity);
tleft = PL_new_term_ref();
for (i = 0; i < arity; i++) {
@@ -975,13 +972,7 @@ PyObject *compound_to_pytree(term_t t, functor_t fun) {
/* pArg reference stolen here: */
PyTuple_SET_ITEM(o, i, pArg);
}
if (PyObject_HasAttrString(py_Yapex, "T"))
c = PyObject_GetAttrString(py_Yapex, "T");
o1 = PyTuple_New(2);
PyTuple_SET_ITEM(o1, 0, PyUnicode_FromString(s));
PyTuple_SET_ITEM(o1, 1, o);
return o1;
#endif
return term_to_nametuple(s, arity, t);
}
}

View File

@@ -4,7 +4,7 @@
int assign_python(PyObject *root, term_t t, PyObject *e);
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;
functor_t FUNCTOR_dollar1, FUNCTOR_abs1, FUNCTOR_all1, FUNCTOR_any1,
FUNCTOR_bin1, FUNCTOR_brackets1, FUNCTOR_comma2, FUNCTOR_dir1,
@@ -12,8 +12,7 @@ functor_t FUNCTOR_dollar1, FUNCTOR_abs1, FUNCTOR_all1, FUNCTOR_any1,
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_colon2, FUNCTOR_equal2, FUNCTOR_sqbrackets2, FUNCTOR_dot2;
PyObject *py_Main;
PyObject *py_Builtin;
@@ -103,7 +102,7 @@ X_API bool init_python(void) {
Py_SetProgramName(argv[0]);
#else
wchar_t *buf = Py_DecodeLocale(argv[0], NULL);
Py_SetProgramName(buf);
Py_SetProgramName(buf);
#endif
}
Py_Initialize();
@@ -112,6 +111,6 @@ X_API bool init_python(void) {
PL_reset_term_refs(t);
install_pypreds();
install_pl2pl();
//PyGILState_Release(gstate);
// PyGILState_Release(gstate);
return !python_in_python;
}

View File

@@ -93,6 +93,8 @@ static inline PyObject *atom_to_python_string(term_t t) {
}
}
extern PyObject *term_to_nametuple(const char *s, int arity, term_t t);
extern PyObject *compound_to_pyeval(term_t t, functor_t fun);
extern PyObject *compound_to_pytree(term_t t, functor_t fun);

View File

@@ -1,24 +1,7 @@
import yap
import sys
# this class is not being used
# we rely on namedtuples instead.
class T(tuple):
"""Represents a non-interned Prolog atom"""
def __new__(self, s, tple):
self.tuple.__new__(self, tple)
self.name = s
def __repr__(self):
return "yapex.T(" + self.name + " , " + tuple.__repr__(self) + ")"
def __str__(self):
return str(self.name) + str(self.tuple)
import collections
def query_prolog(engine, s):
@@ -29,38 +12,58 @@ def query_prolog(engine, s):
print(e.args[1])
return False
#construct a query from a one-line string
# q is opaque to Python
q = engine.query(s)
# vs is the list of variables
# you can print it out, the left-side is the variable name,
# the right side wraps a handle to a variable
vs= q.namedVars()
# atom match either symbols, or if no symbol exists, sttrings, In this case
# variable names should match strings
for eq in vs:
if not isinstance(eq[0],str):
print( "Error: Variable Name matches a Python Symbol")
return
ask = True
# launch the query
while answer(q):
vs = q.namedVarsCopy()
if vs:
i = 0
for eq in vs:
name = eq[0]
bind = eq[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())
# this new vs should contain bindings to vars
vs= q.namedVars()
#numbervars
i=0
# iteratw
for eq in vs:
name = eq[0]
# this is tricky, we're going to bind the variables in the term so thay we can
# output X=Y. The Python way is to use dictionares.
#Instead, we use the T function to tranform the Python term back to Prolog
binding = yap.T(eq[1])
if binding.isVar():
binding.unify(name)
else:
i = binding.numberVars(i, True)
print(name + " = " + binding.text())
#ok, that was Prolog code
print("yes")
# deterministic = one solution
if q.deterministic():
# done
q.close()
return
if ask:
s = input("more(;/y), all(!/a), no ?").lstrip()
s = input("more(;), all(*), no(\\n), python(#) ?").lstrip()
if s.startswith(';') or s.startswith('y'):
continue
elif s.startswith('#'):
exec(s.lstrip('#'))
elif s.startswith('a'):
elif s.startswith('*') or s.startswith('a'):
ask = False
continue
else:
break
print("No (more) answers")
q.close()
print("No (more) answers")
q.close()
return