From 18e437f038eec691003fef130b235c0157048f1e Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Mon, 10 Dec 2018 22:40:12 +0000 Subject: [PATCH 01/14] yapi --- misc/editors/prolog.js | 117 ++++++++++++++---- packages/ProbLog/problog.md | 7 +- packages/python/python.c | 14 +++ .../yap_kernel/yap_ipython/prolog/jupyter.yap | 4 +- .../python/yap_kernel/yap_ipython/yapi.py | 1 - 5 files changed, 112 insertions(+), 31 deletions(-) diff --git a/misc/editors/prolog.js b/misc/editors/prolog.js index a9c36aba1..9476ce5ef 100644 --- a/misc/editors/prolog.js +++ b/misc/editors/prolog.js @@ -3,9 +3,9 @@ (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("codemirror/lib/codemirror")); + mod(require([ "codemirror/lib/codemirror", "codemirror/addon/lint/lint" ])); else if (typeof define == "function" && define.amd) // AMD - define([ "codemirror/lib/codemirror" ], mod); + define([ "codemirror/lib/codemirror", "codemirror/addon/lint/lint" ], mod); else // Plain browser env mod(CodeMirror); })(function(CodeMirror) { @@ -34,9 +34,26 @@ CodeMirror.defineMode("prolog", function(conf, parserConfig) { parserConfig.groupedIntegers || false; /* tag{k:v, ...} */ var unicodeEscape = parserConfig.unicodeEscape || true; /* \uXXXX and \UXXXXXXXX */ - var multiLineQuoted = parserConfig.multiLineQuoted || true; /* "...\n..." */ - var quoteType = parserConfig.quoteType || - {'"' : "string", "'" : "qatom", "`" : "bqstring"}; + var multiLineQuoted = parserConfig.multiLineQuotedd || true; + var singleQuoted = "atom"; + if (parserConfig.singleQuote === "string" || +parserConfig.singleQuote === "codes" || +parserConfig.singleQuote === "chars") + singleQuoted = parserConfig.singleQuote; + var doubleQuoted = "string"; + if (parserConfig.doubleQuote === "atom" || +parserConfig.doubleQuote === "codes" || +parserConfig.doubleQuote === "chars") + doubleQuoted = parserConfig.doubleQuote; + var backQuoted = "atom"; + if (parserConfig.backQuote === "string" || +parserConfig.backQuote === "codes" || +parserConfig.backQuote === "chars") + backQuoted = parserConfig.backQuote; + + var quoteType = {"\"" : doubleQuoted, "`" : backQuoted, "'" : singleQuoted}; + + var singletonVars = new Map(); var isSingleEscChar = /[abref\\'"nrtsv]/; var isOctalDigit = /[0-7]/; @@ -64,7 +81,7 @@ CodeMirror.defineMode("prolog", function(conf, parserConfig) { function rmError(stream) { if (cm_ == null) - return; + return; var doc = cm_.getDoc(); var l = getLine(stream); // stream.lineOracle.line; @@ -73,7 +90,6 @@ CodeMirror.defineMode("prolog", function(conf, parserConfig) { if (elLine == null || l === elLine) { errorFound.splice(i, 1); i -= 1; - console.log(-elLine); } } } @@ -85,8 +101,8 @@ CodeMirror.defineMode("prolog", function(conf, parserConfig) { var found = errorFound.find(function( element) { return element.line === l && element.to == stream.pos; }); if (!found) { - console.log( getLine(stream) ); - errorFound.push({ + //console.log(getLine(stream)); + errorFound.push({ "line" : l, "from" : stream.start, "to" : stream.pos, @@ -120,6 +136,30 @@ CodeMirror.defineMode("prolog", function(conf, parserConfig) { return exportedMsgs; } + function maybeSingleton(stream, key) { + //console.log(key); + var v = singletonVars.get(key); + if (v != undefined) { + v.singleton = false; + } else { + singletonVars.set( + key, {'singleton' : true, 'from' : stream.start, to : stream.pos}); + } + //console.log(singletonVars); + } + + function outputSingletonVars(stream) { + var key, v; + for (var key in singletonVars.keys()) { + var v = singletonVars[key]; + if (v != undefined && v.singleton) { + mkError(stream, "warning", key + " singleton variable"); + } + } + singletonVars.clear(); + // console.log("reset"); + } + CodeMirror.registerHelper("lint", "prolog", exportErrors); /******************************* @@ -260,6 +300,8 @@ CodeMirror.defineMode("prolog", function(conf, parserConfig) { function plTokenBase(stream, state) { var ch = stream.next(); + state.curToken = ch; + if (ch == "(") { if (state.lastType == "functor") { state.nesting.push({ @@ -323,22 +365,38 @@ CodeMirror.defineMode("prolog", function(conf, parserConfig) { state.commaAtEOL = true; nextArg(state); /*FALLTHROUGH*/ + if (!state.commaAtEOL) + stream.eatSpace(); + var nch = stream.peek(); + if (nch == ';' || nch == ',') { + mkError(stream, "error", "\",\" followed by " + stream.peek()); + return ret("solo", "error", ","); + } if (isControl(state)) { - if (!state.commaAtEOL) - stream.eatSpace(); - if (!stream.peek("[")) { + if ("[" != ch) { if (state.inBody) { state.goalStart = true; } else { + mkError(stream, "error", "\",\" followed by " + stream.peek()); return ret("solo", "error", ","); } } } + return ret('solo', 'tag', ","); } break; case ";": + if (!state.commaAtEOL) + stream.eatSpace(); + ch = stream.peek(); + if (ch == ';' || ch == ',') { + mkError(stream, "error", "\",\" followed by " + stream.peek()); + return ret("solo", "error", ";"); + } if (isControl(state)) { - if (!state.inBody) + if (!state.inBody) { + mkError(stream, "error", "unexpected ;"); return ret("solo", "error", ";"); + } state.goalStart = true; } break; @@ -399,8 +457,10 @@ CodeMirror.defineMode("prolog", function(conf, parserConfig) { if (stream.eat(/'/)) { /* 0' */ var next = stream.next(); if (next == "\\") { - if (!readEsc(stream)) + if (!readEsc(stream)) { + mkError(stream, "error", "bad escape"); return ret("error", "error"); + } } return ret("code", "number"); } @@ -423,16 +483,20 @@ CodeMirror.defineMode("prolog", function(conf, parserConfig) { mkError(stream, "error", "Clause over before closing all brackets"); state.nesting = []; } - // var start = cm_.getCursor("end"); - //cm_.setBookmark(start, {"widget" : document.createTextNode("•")}); + // var start = cm_.getCursor("end"); + // cm_.setBookmark(start, {"widget" : + // document.createTextNode("•")}); state.inBody = false; state.goalStart = true; + outputSingletonVars(stream); stream.eat(ch); return ret("fullstop", "def", atom); } else { if (atom === ":-" && state.headStart) { - + state.headStart = false; + state.inBody = true; + state.goalStart = true; return ret("directive", "attribute", atom); } else if (isNeck.test(atom)) { @@ -463,12 +527,14 @@ CodeMirror.defineMode("prolog", function(conf, parserConfig) { stream.eatWhile(/[\w_]/); if (ch == ".") { + mkError(stream, "error", "bad dotted name"); return ret("atom", "error"); } } } } var word = stream.current(); + state.curToken = word; var extra = ""; if (stream.peek() == "{" && dicts) { state.tagName = word; /* tmp state extension */ @@ -478,14 +544,13 @@ CodeMirror.defineMode("prolog", function(conf, parserConfig) { if (word.length == 1) { return ret("var", "variable-2", word); } else { - var sec = word.charAt(1); - if (sec == sec.toUpperCase()) - return ret("var", "variable-2", word); + return ret("var", "variable-2", word); } - return ret("var", "variable-2", word); - } else if (ch == ch.toUpperCase()) { + } else if (ch.match(/[A-Z]/)) { + maybeSingleton(stream, word); return ret("var", "variable-1", word); - } else if (stream.peek() == "(") { + } + if (stream.peek() == "(") { state.functorName = word; /* tmp state extension */ state.functorColumn = stream.column(); if (state.headStart) { @@ -519,8 +584,9 @@ CodeMirror.defineMode("prolog", function(conf, parserConfig) { if (builtins[word] && isControl(state)) return ret("functor", "keyword", w); return ret("functor", "atom", w); - } else if (builtins[word] && isControl(state)) + } else if (builtins[word] && isControl(state)) { return ret("atom", "keyword", word); + } return ret("atom", "atom", word); } @@ -1340,6 +1406,7 @@ IfTrue rmError(stream); var style = state.tokenize(stream, state); + //console.log(state.curToken); if (stream.eol()) { if (stream.pos > 0) @@ -1386,7 +1453,7 @@ IfTrue blockCommentEnd : "*/", blockCommentContinue : " * ", comment : "%", - fold : "indent" + matchBrackets : true }; return external; }); diff --git a/packages/ProbLog/problog.md b/packages/ProbLog/problog.md index ede92c3d6..9f48f663f 100644 --- a/packages/ProbLog/problog.md +++ b/packages/ProbLog/problog.md @@ -1,12 +1,13 @@ -The Problog-I Language and Learning System {#problog} -===================================== +@defgroup problog The Problog-I Language and Learning System -[TOC] +@{ This document is intended as a user guide for the users of ProbLog-I. ProbLog is a probabilistic Prolog, a probabilistic logic programming language, which is integrated in YAP-Prolog. Most of the work in ProbLog is now based on(Prolog-II), but we still maintain ProbLog-I in order to experiment with close integration of probabilistic nd logical systems. +[TOC] + @section InstallingProbLog Installing ProbLog diff --git a/packages/python/python.c b/packages/python/python.c index ca176ebb5..7738d277b 100644 --- a/packages/python/python.c +++ b/packages/python/python.c @@ -1,4 +1,16 @@ +/** + * @file python.c + * + * @brief data structures and init for Py4YAP library + * + */ +/** + * @defgroup PY4YAP + * @ingroup python + * @brief make Python talk to YAP + * @{ + */ #include "py4yap.h" #include @@ -127,3 +139,5 @@ X_API bool do_init_python(void) { // python_output(); return true; } + +// @} diff --git a/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap b/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap index fb5f2618f..9a928589f 100644 --- a/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap +++ b/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap @@ -88,11 +88,11 @@ blank(Text) :- streams(false) :- - close(user_input), + %close(user_input), close(user_output), close(user_error). streams( true) :- - open('/python/input', read, _Input, [alias(user_input),bom(false),script(false)]), + %open('/python/input', read, _Input, [alias(user_input),bom(false),script(false)]), open('/python/sys.stdout', append, _Output, [alias(user_output)]), open('/python/sys.stderr', append, _Error, [alias(user_error)]). diff --git a/packages/python/yap_kernel/yap_ipython/yapi.py b/packages/python/yap_kernel/yap_ipython/yapi.py index b3dfea435..af65e8ee5 100644 --- a/packages/python/yap_kernel/yap_ipython/yapi.py +++ b/packages/python/yap_kernel/yap_ipython/yapi.py @@ -704,7 +704,6 @@ class YAPRun(InteractiveShell): else: linec = True rcell = cell[1:].strip() - print(cell) try: [magic,cell] = rcell.split(maxsplit = 1, sep = '\n') except: From 13a6cc8ececa541d38e919945cbb53c0c4c751ce Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Mon, 10 Dec 2018 22:55:52 +0000 Subject: [PATCH 02/14] fix prolog mode --- misc/editors/prolog.js | 92 ++++++++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 39 deletions(-) diff --git a/misc/editors/prolog.js b/misc/editors/prolog.js index 9476ce5ef..72bd11c26 100644 --- a/misc/editors/prolog.js +++ b/misc/editors/prolog.js @@ -2,14 +2,14 @@ // Distributed under an MIT license: http://codemirror.net/LICENSE (function(mod) { -if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require([ "codemirror/lib/codemirror", "codemirror/addon/lint/lint" ])); -else if (typeof define == "function" && define.amd) // AMD - define([ "codemirror/lib/codemirror", "codemirror/addon/lint/lint" ], mod); -else // Plain browser env - mod(CodeMirror); + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); })(function(CodeMirror) { -"use strict"; + "use strict"; CodeMirror.defineMode("prolog", function(conf, parserConfig) { function chain(stream, state, f) { @@ -17,7 +17,8 @@ CodeMirror.defineMode("prolog", function(conf, parserConfig) { return f(stream, state); } - var cm_; + var cm_ = null; +var document = CodeMirror.doc; var curLine; /******************************* @@ -72,21 +73,20 @@ parserConfig.backQuote === "chars") var exportedMsgs = []; function getLine(stream) { +if (stream) return stream.lineOracle.line; - // return cm_.getDoc().getCursor().line; + if (document == null) + return 0; + return document.getCursor().line; } // var ed = // window.document.getElementsByClassName("CodeMirror")[0].CodeMirror.doc.getEditor(); - function rmError(stream) { - if (cm_ == null) - return; - var doc = cm_.getDoc(); + function rmError(document,stream) { var l = getLine(stream); - // stream.lineOracle.line; for (var i = 0; i < errorFound.length; i++) { - var elLine = doc.getLineNumber(errorFound[i].line); + var elLine = errorFound[i].document.getLineNumber(errorFound[i].line); if (elLine == null || l === elLine) { errorFound.splice(i, 1); i -= 1; @@ -97,7 +97,7 @@ parserConfig.backQuote === "chars") function mkError(stream, severity, msg) { if (stream.pos == 0) return; - var l = cm_.getDoc().getLineHandle(getLine(stream)); + var l = getLine(stream); var found = errorFound.find(function( element) { return element.line === l && element.to == stream.pos; }); if (!found) { @@ -107,20 +107,19 @@ parserConfig.backQuote === "chars") "from" : stream.start, "to" : stream.pos, severity : severity, - message : msg + message : msg, +document: document }); } } function exportErrors(text) { - if (cm_ == null) + if (document == null) return; - var doc = cm_.getDoc(); - exportedMsgs.length = 0; for (var i = 0; i < errorFound.length; i += 1) { var e = errorFound[i]; - var l = doc.getLineNumber(e.line); + var l = document.getLineNumber(e.line); if (l == null) { errorFound.splice(i, 1); i -= 1; @@ -324,6 +323,7 @@ parserConfig.backQuote === "chars") if (ch == "{" && state.lastType == "tag") { state.nesting.push({ + marker: ch, tag : state.tagName, column : stream.column(), leftCol : state.tagColumn, @@ -334,8 +334,12 @@ parserConfig.backQuote === "chars") return ret("dict_open", "bracket"); } - if (ch == "/" && stream.eat("*")) - return chain(stream, state, plTokenComment); + if (ch == "/") { +var next = stream.peek(); +if (next == '*') { + return chain(stream, state, plTokenComment); + } + } if (ch == "%") { stream.skipToEnd(); @@ -347,14 +351,22 @@ parserConfig.backQuote === "chars") if (isSoloChar.test(ch)) { switch (ch) { case ")": { +if (state.nesting.marker != "(") { + mkError(stream, "error", state.nesting.marker + " closed by )"); +} state.nesting.pop(); } break; case "]": - +if (state.nesting.marker != "[") { + mkError(stream, "error", state.nesting.marker + " closed by ]"); +} state.nesting.pop(); return ret("list_close", "bracket"); case "}": { - var nest = nesting(state); + if (state.nesting.marker != "{") { + mkError(stream, "error", state.nesting.marker + " closed by }"); +} + var nest = nesting(state); var type = (nest && nest.tag) ? "dict_close" : "brace_term_close"; state.nesting.pop(); @@ -490,6 +502,7 @@ parserConfig.backQuote === "chars") state.goalStart = true; outputSingletonVars(stream); stream.eat(ch); +state.headStart = true; return ret("fullstop", "def", atom); } else { @@ -502,7 +515,7 @@ parserConfig.backQuote === "chars") } else if (isNeck.test(atom)) { state.inBody = true; state.goalStart = true; - return ret("neck", "property", atom); + return ret("neck", "def", atom); } else if (isControl(state) && isControlOp.test(atom)) { state.goalStart = true; return ret("symbol", "meta", atom); @@ -510,7 +523,7 @@ parserConfig.backQuote === "chars") return ret("symbol", "meta", atom); } } - stream.eatWhile(/[\w_]/); + stream.eatWhile(/\w/); if (composeGoalWithDots) { while (stream.peek() == ".") { stream.eat('.'); @@ -519,8 +532,8 @@ parserConfig.backQuote === "chars") stream.backUp(1); break; - } else if (/[\w_]/.test(ch)) { - stream.eatWhile(/[\w_]/); + } else if (/\w/.test(ch)) { + stream.eatWhile(/\w/); } else if (ch == "'") { stream.eat(); @@ -550,17 +563,20 @@ parserConfig.backQuote === "chars") maybeSingleton(stream, word); return ret("var", "variable-1", word); } - if (stream.peek() == "(") { - state.functorName = word; /* tmp state extension */ - state.functorColumn = stream.column(); - if (state.headStart) { +if (state.headStart) { state.headStart = false; - if (state.headFunctor != word) { + if (state.headFunctor !== word) { state.headFunctor = word; return ret("functor", "def", word); } +return ret("functor", "atom", word); + } - if (builtins[word] && isControl(state)) + + if (stream.peek() == "(") { + state.functorName = word; /* tmp state extension */ + state.functorColumn = stream.column(); + if (builtins[word] && isControl(state)) return ret("functor", "keyword", word); return ret("functor", "atom", word); } else if ((extra = stream.eatSpace())) { @@ -732,8 +748,8 @@ IfTrue CodeMirror.defineOption( "prologKeys", true, function(cm, editor, prev) { - cm_ = cm; - if (prev && prev != CodeMirror.Init) + document = cm.getDoc(); + if (nnprev && prev != CodeMirror.Init) cm.removeKeyMap("prolog"); if (true) { var map = { @@ -1402,8 +1418,6 @@ IfTrue setArgAlignment(state); return null; } - if (state.curLine == null || state.pos == 0) - rmError(stream); var style = state.tokenize(stream, state); //console.log(state.curToken); From afe5780fc15f64635bdcd5505fc854152d772c38 Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Tue, 11 Dec 2018 08:16:54 +0000 Subject: [PATCH 03/14] bad chars? --- packages/python/swig/prolog/yapi.yap | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/python/swig/prolog/yapi.yap b/packages/python/swig/prolog/yapi.yap index 23da8e0f5..37047c60e 100644 --- a/packages/python/swig/prolog/yapi.yap +++ b/packages/python/swig/prolog/yapi.yap @@ -78,13 +78,17 @@ python_query( Caller, String ) :- maplist(in_dict(Caller.answer), Bindings). -in_dict(Dict, var([V0,V|Vs])) :- !, - Dict[V] := V0, +in_dict(Dict, var([V0,V|Vs])) :- + !, + atom_string(V0,S0), + atom_string(V,S), + Dict[S] := S0, in_dict( Dict, var([V0|Vs])). -in_dict(_Dict, var([_],_G)) :- !. -in_dict(Dict, nonvar([V0|Vs],G)) :- !, -term_to_atom(G,A,_), - Dict[V0] := A, - in_dict( Dict, nonvar(Vs, G) ). -in_dict(_Dict, nonvar([],_G)) :- !. -in_dict(_, _) +in_dict(Dict, nonvar([V0|Vs], T)) :- + !, + atom_string(V0,S0), + atom_string(T,S), + Dict[S0] := S, + in_dict( Dict, var([V0|Vs])). +in_dict(_,_). + From 7e84455117d6612033c16028204b7bb66e7fcbbb Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Tue, 11 Dec 2018 12:50:52 +0000 Subject: [PATCH 04/14] yap --- misc/backcall-0.1.0-cp36-none-any.whl | Bin 11964 -> 0 bytes os/readterm.c | 2 +- os/writeterm.c | 5 +- packages/python/swig/README.md | 45 +++++++----------- packages/python/swig/prolog/yapi.yap | 26 +++++----- .../yap_ipython/core/interactiveshell.py | 2 +- .../yap_kernel/yap_ipython/prolog/jupyter.yap | 8 ++-- .../python/yap_kernel/yap_ipython/yapi.py | 13 ++--- 8 files changed, 47 insertions(+), 54 deletions(-) delete mode 100644 misc/backcall-0.1.0-cp36-none-any.whl diff --git a/misc/backcall-0.1.0-cp36-none-any.whl b/misc/backcall-0.1.0-cp36-none-any.whl deleted file mode 100644 index c08fa1b1527e860e1c78bd5de7fd4061d7766cfb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11964 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 XryV6ZNT|OW!2Z7e+G#$}|5f{c1p53t diff --git a/os/readterm.c b/os/readterm.c index f7122186d..74d5e419b 100644 --- a/os/readterm.c +++ b/os/readterm.c @@ -904,7 +904,7 @@ static Term syntax_error(TokEntry *errtok, int sno, Term cmod, Int newpos, bool v_vnames = get_varnames(fe, tokstart); else v_vnames = 0L; - if (fe->t && trueGlobalPrologFlag(SINGLE_VAR_WARNINGS_FLAG)) + if (fe->t && fe->reading_clause && trueGlobalPrologFlag(SINGLE_VAR_WARNINGS_FLAG)) { warn_singletons(fe, tokstart); } diff --git a/os/writeterm.c b/os/writeterm.c index 972af199e..715d84e3c 100644 --- a/os/writeterm.c +++ b/os/writeterm.c @@ -680,12 +680,13 @@ static Int term_to_string(USES_REGS1) { } return Yap_unify(ARG2, MkStringTerm(s)); } else if (!IsStringTerm(t2)) { - Yap_Error(TYPE_ERROR_STRING, t2, "string_to_ter®m/2"); + Yap_Error(TYPE_ERROR_STRING, t2, "term_to_string/3"); return false; } else { s = StringOfTerm(t2); } - return (rc = readFromBuffer(s, TermNil)) != 0L && Yap_unify(rc, ARG1); + yhandle_t y1 = Yap_InitHandle( t1 ); + return (rc = readFromBuffer(s, TermNil)) != 0L && Yap_unify(rc, Yap_PopHandle(y1)); } static Int term_to_atom(USES_REGS1) { diff --git a/packages/python/swig/README.md b/packages/python/swig/README.md index d609f6392..90f64fe05 100644 --- a/packages/python/swig/README.md +++ b/packages/python/swig/README.md @@ -1,14 +1,16 @@ +The YAP Prolog System {#main} +=========== -
![The YAP Logo](docs/icons/yap_128x128x32.png)
NOTE: this version of YAP is still experimental, documentation may be out of date. -## Introduction +Introduction +++++++++++ This document provides User information on version 6.3.4 of -YAP (Yet Another Prolog). The YAP Prolog System is a +YAP (*Yet Another Prolog*). The YAP Prolog System is a high-performance Prolog compiler developed at Universidade do Porto. YAP supports stream Input/Output, sockets, modules, exceptions, Prolog debugger, C-interface, dynamic code, internal @@ -16,7 +18,6 @@ Porto. YAP supports stream Input/Output, sockets, modules, We explicitly allow both commercial and non-commercial use of YAP. - YAP is based on the David H. D. Warren's WAM (Warren Abstract Machine), with several optimizations for better performance. YAP follows the Edinburgh tradition, and was originally designed to be largely @@ -47,47 +48,33 @@ different licenses. If you have a question about this software, desire to add code, found a bug, want to request a feature, or wonder how to get further assistance, -please send e-mail to . To -subscribe to the mailing list, visit the page -. +please send e-mail to `yap-users AT lists.sourceforge.net. To +subscribe to the mailing list, visit the [YAP Mailing list page](https://lists.sourceforge.net/lists/listinfo/yap-users). On-line documentation is available for [YAP](http://www.dcc.fp.pt/~vsc/yap/) - - The packages are, in alphabetical order: -+ The CHR package developed by Tom Schrijvers, -Christian Holzbaur, and Jan Wielemaker. ++ The CHR package developed by Tom Schrijvers, Christian Holzbaur, and Jan Wielemaker. + The CLP(BN) package and Horus toolkit developed by Tiago Gomes, and Vítor Santos Costa. -+ The CLP(R) package developed by Leslie De Koninck, Bart Demoen, Tom -Schrijvers, and Jan Wielemaker, based on the CLP(Q,R) implementation -by Christian Holzbaur. ++ The CLP(R) package developed by Leslie De Koninck, Bart Demoen, Tom Schrijvers, and Jan Wielemaker, based on the CLP(Q,R) implementation by Christian Holzbaur. -+ The CPLint package developed by Fabrizio Riguzzi's research -laboratory at the [University of Ferrara](http://www.ing.unife.it/Docenti/FabrizioRiguzzi/) ++ The CPLint package developed by Fabrizio Riguzzi's research laboratory at the [University of Ferrara](http://www.ing.unife.it/Docenti/FabrizioRiguzzi/). -+ The CUDA interface package developed by Carlos Martínez, Jorge -Buenabad, Inês Dutra and Vítor Santos Costa. ++ The CUDA interface package developed by Carlos Martínez, Jorge Buenabad, Inês Dutra and Vítor Santos Costa. + The [GECODE](http://www.gecode.org) interface package developed by Denys Duchier and Vítor Santos Costa. + The [JPL](http://www.swi-prolog.org/packages/jpl/) (Java-Prolog Library) package developed by . - The minisat SAT solver interface developed by Michael Codish, - Vitaly Lagoon, and Peter J. Stuckey. ++ The minisat SAT solver interface developed by Michael Codish, Vitaly Lagoon, and Peter J. Stuckey. -+ The MYDDAS relational data-base interface developed at the - Universidade do Porto by Tiago Soares, Michel Ferreira, and Ricardo Rocha. ++ The MYDDAS relational data-base interface developed at the Universidade do Porto by Tiago Soares, Michel Ferreira, and Ricardo Rocha. -+ The [PRISM](http://rjida.meijo-u.ac.jp/prism/) logic-based -programming system for statistical modeling developed at the Sato -Research Laboratory, TITECH, Japan. ++ The [PRISM](http://rjida.meijo-u.ac.jp/prism/) logic-based programming system for statistical modeling developed at the Sato Research Laboratory, TITECH, Japan. -+ The ProbLog 1 system developed by the [ProbLog](https://dtai.cs.kuleuven.be/problog) team in the -DTAI group of KULeuven. ++ The ProbLog 1 system developed by the [ProbLog](https://dtai.cs.kuleuven.be/problog) team in the DTAI group of KULeuven. -+ The [R](http://stoics.org.uk/~nicos/sware/packs/real/) interface package developed by Nicos Angelopoulos, -Vítor Santos Costa, João Azevedo, Jan Wielemaker, and Rui Camacho. ++ The [R](http://stoics.org.uk/~nicos/sware/packs/real/) interface package developed by Nicos Angelopoulos, Vítor Santos Costa, João Azevedo, Jan Wielemaker, and Rui Camacho. diff --git a/packages/python/swig/prolog/yapi.yap b/packages/python/swig/prolog/yapi.yap index 37047c60e..5fca3bce8 100644 --- a/packages/python/swig/prolog/yapi.yap +++ b/packages/python/swig/prolog/yapi.yap @@ -75,20 +75,24 @@ python_query( Caller, String ) :- write_query_answer( Bindings ), nl(user_error), Caller.answer := {}, - maplist(in_dict(Caller.answer), Bindings). + maplist(in_dict(Caller.answer, Bindings), Bindings). - -in_dict(Dict, var([V0,V|Vs])) :- +/** + * + */ +in_dict(_Dict, _, var([_V0])) :- + !. +in_dict(Dict, Bindings, var([V0,V|Vs])) :- !, - atom_string(V0,S0), - atom_string(V,S), + atom_to_string(V0,S0), + atom_to_string(V,S), Dict[S] := S0, - in_dict( Dict, var([V0|Vs])). -in_dict(Dict, nonvar([V0|Vs], T)) :- + in_dict( Dict, Bindings, var([V0|Vs])). +in_dict(Dict, Bindings, nonvar([V0|Vs], T)) :- !, - atom_string(V0,S0), - atom_string(T,S), + atom_to_string(V0,S0), + term_to_string(T, S, _Bindings), Dict[S0] := S, - in_dict( Dict, var([V0|Vs])). -in_dict(_,_). + in_dict( Dict, Bindings, var([V0|Vs])). +in_dict(_, _, _). diff --git a/packages/python/yap_kernel/yap_ipython/core/interactiveshell.py b/packages/python/yap_kernel/yap_ipython/core/interactiveshell.py index cd60ec2b2..626bddb55 100644 --- a/packages/python/yap_kernel/yap_ipython/core/interactiveshell.py +++ b/packages/python/yap_kernel/yap_ipython/core/interactiveshell.py @@ -2040,7 +2040,7 @@ class InteractiveShell(SingletonConfigurable): list where you want the completer to be inserted.""" newcomp = types.MethodType(completer,self.Completer) - self.Completer.matchers.insert(pos,newcomp) + self.Completer.matches.insert(pos,newcomp) def set_completer_frame(self, frame=None): """Set the frame of the completer.""" diff --git a/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap b/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap index 9a928589f..4b4be4e88 100644 --- a/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap +++ b/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap @@ -38,7 +38,7 @@ jupyter_cell( _Caller, _, Line ) :- blank( Line ), !. jupyter_cell(Caller, _, Line ) :- - Query = Caller, + Query = Caller, catch( python_query(Query,Line), error(A,B), @@ -67,7 +67,7 @@ jupyter_consult(Cell) :- ( Options = [], open_mem_read_stream( Cell, Stream), - load_files(user:'jupyter cell',[stream(Stream)| Options]) + load_files(Stream,[stream(Stream)| Options]) ), error(A,B), (close(Stream), system_error(A,B)) @@ -88,11 +88,11 @@ blank(Text) :- streams(false) :- - %close(user_input), + close(user_input), close(user_output), close(user_error). streams( true) :- - %open('/python/input', read, _Input, [alias(user_input),bom(false),script(false)]), + open('/python/input', read, _Input, [alias(user_input),bom(false),script(false)]), open('/python/sys.stdout', append, _Output, [alias(user_output)]), open('/python/sys.stderr', append, _Error, [alias(user_error)]). diff --git a/packages/python/yap_kernel/yap_ipython/yapi.py b/packages/python/yap_kernel/yap_ipython/yapi.py index af65e8ee5..92735de00 100644 --- a/packages/python/yap_kernel/yap_ipython/yapi.py +++ b/packages/python/yap_kernel/yap_ipython/yapi.py @@ -739,12 +739,13 @@ class YAPRun(InteractiveShell): # def f(self, cell, state): # state = self.jupyter_query( cell ) - # run the new command using the given tracer - # - # tracer.runfunc(f,self,cell,state) - self.jupyter_query( cell ) - # state = tracer.runfunc(jupyter_query( self, cell ) ) + # run the new command using the given tracer + # + # tracer.runfunc(f,self,cell,state) + self.jupyter_query( cell ) + # state = tracer.runfunc(jupyter_query( self, cell ) ) self.shell.last_execution_succeeded = True + result.info += [self.answer] result.result = True except Exception as e: has_raised = True @@ -773,7 +774,7 @@ class YAPRun(InteractiveShell): self.shell.execution_count += 1 self.yapeng.mgoal(streams(False),"user", True) - return result + return result.result def clean_end(self,s): """ From 473132c3ec0d5cdb0f1daa8f790b17a646329f91 Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Wed, 12 Dec 2018 00:39:17 +0000 Subject: [PATCH 05/14] yapi --- packages/python/pyio.c | 4 +- packages/python/swig/prolog/yapi.yap | 3 +- .../python/yap_kernel/yap_ipython/yapi.py | 47 ++++++++----------- pl/top.yap | 9 ++-- 4 files changed, 26 insertions(+), 37 deletions(-) diff --git a/packages/python/pyio.c b/packages/python/pyio.c index 6647ff6be..8e16fa55d 100644 --- a/packages/python/pyio.c +++ b/packages/python/pyio.c @@ -11,7 +11,7 @@ YAP_Term TermErrStream, TermOutStream; static void pyflush(StreamDesc *st) { #if 0 st->u.w_irl.ptr[0] = '\0'; - fprintf(stderr,"%s\n", st->u.w_irl.buf); + // fprintf(stderr,"%s\n", st->u.w_irl.buf); term_t tg = python_acquire_GIL(); if (st->user_name == TermOutStream){ PySys_WriteStdout("%s", st->u.w_irl.buf); @@ -103,7 +103,7 @@ static void *py_open(VFS_t *me, const char *name, const char *io_mode, if (pystream == NULL || pystream == Py_None) { python_release_GIL(ctk); return NULL; - } + } StreamDesc *st = YAP_RepStreamFromId(sno); st->name = YAP_LookupAtom(name); if (strcmp(name, "sys.stdout") == 0 || strcmp(name, "sys.stderr") == 0 || diff --git a/packages/python/swig/prolog/yapi.yap b/packages/python/swig/prolog/yapi.yap index 5fca3bce8..5cd1303c1 100644 --- a/packages/python/swig/prolog/yapi.yap +++ b/packages/python/swig/prolog/yapi.yap @@ -73,8 +73,7 @@ python_query( Caller, String ) :- query_to_answer( Goal, VarNames, Status, Bindings), Caller.port := Status, write_query_answer( Bindings ), - nl(user_error), - Caller.answer := {}, + nl(user_error), maplist(in_dict(Caller.answer, Bindings), Bindings). /** diff --git a/packages/python/yap_kernel/yap_ipython/yapi.py b/packages/python/yap_kernel/yap_ipython/yapi.py index 92735de00..a735623ef 100644 --- a/packages/python/yap_kernel/yap_ipython/yapi.py +++ b/packages/python/yap_kernel/yap_ipython/yapi.py @@ -522,7 +522,7 @@ class YAPRun(InteractiveShell): self.query = None self.os = None self.it = None - self.port = None + self.port = "None" self.answers = None self.bindings = dicts = [] self.shell.yapeng = self.yapeng @@ -566,42 +566,37 @@ class YAPRun(InteractiveShell): self.query.close() self.query = None self.port = None - self.answers = None + self.answers = [] self.os = program+squery self.iterations = 0 pg = jupyter_query( self, program, squery) self.query = self.yapeng.query(pg) self.answers = [] - self.port = "call" + self.port = "call" + found = False self.answer = {} while self.query.next(): #sys.stderr.write('B '+str( self.answer) +'\n') #sys.stderr.write('C '+ str(self.port) +'\n'+'\n') found = True + print( "uek",self.answer ) self.answers += [self.answer] + print( "ek",self.answers ) self.iterations += 1 - if self.port == "exit": + if self.port == "exit" or stop or howmany == self.iterations: self.os = None - #sys.stderr.write('Done, with'+str(self.answers)+'\n') - result.result = True,self.bindings + self.query.close() + self.query = None + if found: + sys.stderr.write('Completed, with '+str(self.answers)+'\n') + result.result = self.answers return result - if stop or howmany == self.iterations: - result.result = True, self.answers - return result - if found: - sys.stderr.write('Done, with '+str(self.answers)+'\n') - else: - self.os = None - self.query.close() - self.query = None - sys.stderr.write('Fail\n') - result.result = True,self.bindings - return result + except Exception as e: sys.stderr.write('Exception '+str(e)+'in query '+ str(self.query)+ ':'+pg+'\n '+str( self.bindings)+ '\n') has_raised = True - result.result = False + result.result = [] return result @@ -698,8 +693,7 @@ class YAPRun(InteractiveShell): except: line = "" self.shell.last_execution_succeeded = True - self.shell.run_cell_magic(magic, line, body) - result.result = True + result.result = self.shell.run_cell_magic(magic, line, body) return else: linec = True @@ -720,7 +714,7 @@ class YAPRun(InteractiveShell): # can fill in the output value. self.shell.displayhook.exec_result = result if self.syntaxErrors(cell): - result.result = False + result.result = [] return has_raised = False try: @@ -745,11 +739,10 @@ class YAPRun(InteractiveShell): self.jupyter_query( cell ) # state = tracer.runfunc(jupyter_query( self, cell ) ) self.shell.last_execution_succeeded = True - result.info += [self.answer] - result.result = True + result.result = [] except Exception as e: has_raised = True - result.result = False + result.result = [] try: (etype, value, tb) = e traceback.print_exception(etype, value, tb) @@ -774,7 +767,7 @@ class YAPRun(InteractiveShell): self.shell.execution_count += 1 self.yapeng.mgoal(streams(False),"user", True) - return result.result + return def clean_end(self,s): """ @@ -809,7 +802,7 @@ class YAPRun(InteractiveShell): - def prolog_cell(self,s): + 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 diff --git a/pl/top.yap b/pl/top.yap index 7d3483df8..f509bd134 100644 --- a/pl/top.yap +++ b/pl/top.yap @@ -494,9 +494,6 @@ write_query_answer( Bindings ) :- '$write_goal_output'(G1, First, NG, Next, IG), '$write_vars_and_goals'(LG, Next, IG). -'$goal_to_string'(Format, G, String) :- - format(codes(String),Format,G). - '$write_goal_output'(var([V|VL]), First, [var([V|VL])|L], next, L) :- !, ( First = first -> true ; format(user_error,',~n',[]) ), format(user_error,'~a',[V]), @@ -516,14 +513,14 @@ write_query_answer( Bindings ) :- G = [_|_], !, % dump on string first so that we can check whether we actually % had any output from the solver. - '$goal_to_string'(Format, G, String), - ( String == [] -> + term_to_string( G, String), + ( String == `` -> % we didn't IG = NG, First = Next ; % we did ( First = first -> true ; format(user_error,',~n',[]) ), - format(user_error, '~s', [String]), + format(user_error, '~N~s', [String]), NG = [G|IG] ). '$write_goal_output'(_-G, First, [G|NG], next, NG) :- !, From 44be8cf6009fa953f6991c01d41eb2988fb5c6a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADtor=20Santos=20Costa?= Date: Fri, 14 Dec 2018 10:29:12 +0000 Subject: [PATCH 06/14] android --- C/c_interface.c | 47 ++++----- C/yap-args.c | 262 ++++++++++++++++++++++++++++++++++-------------- CMakeLists.txt | 1 + CXX/yapq.hh | 9 ++ config.h.cmake | 2 +- os/assets.c | 10 +- os/iopreds.c | 134 +++++++++++++------------ os/sysbits.c | 2 +- 8 files changed, 294 insertions(+), 173 deletions(-) diff --git a/C/c_interface.c b/C/c_interface.c index 85ce12a72..cafa94147 100755 --- a/C/c_interface.c +++ b/C/c_interface.c @@ -2106,45 +2106,42 @@ X_API void YAP_ClearExceptions(void) { X_API int YAP_InitConsult(int mode, const char *fname, char **full, int *osnop) { - CACHE_REGS - int sno; - BACKUP_MACHINE_REGS(); - const char *fl = NULL; - int lvl = push_text_stack(); - if (mode == YAP_BOOT_MODE) { - mode = YAP_CONSULT_MODE; - } - if (fname == NULL || fname[0] == '\0') { - fl = Yap_BOOTFILE; - } - if (fname) { - fl = Yap_AbsoluteFile(fname, true); - if (!fl || !fl[0]) { - pop_text_stack(lvl); - *full = NULL; - return -1; - } else { - *full = pop_output_text_stack(lvl, fl); + CACHE_REGS + int sno; + BACKUP_MACHINE_REGS(); + const char *fl = NULL; + if (mode == YAP_BOOT_MODE) { + mode = YAP_CONSULT_MODE; } - } else { - pop_text_stack(lvl); + if (fname == NULL || fname[0] == '\0') { + fl = Yap_BOOTFILE; + } + if (!fname || !(fl = Yap_AbsoluteFile(fname, true)) || !fl[0]) { + __android_log_print( + ANDROID_LOG_INFO, "YAPDroid", "failed ABSOLUTEFN %s ", fl); + *full = NULL; + return -1; } + __android_log_print( + ANDROID_LOG_INFO, "YAPDroid", "done init_ consult %s ",fl); - lvl = push_text_stack(); +int lvl = push_text_stack(); char *d = Malloc(strlen(fl) + 1); strcpy(d, fl); bool consulted = (mode == YAP_CONSULT_MODE); Term tat = MkAtomTerm(Yap_LookupAtom(d)); sno = Yap_OpenStream(tat, "r", MkAtomTerm(Yap_LookupAtom(fname)), LOCAL_encoding); - if (sno < 0 || !Yap_ChDir(dirname((char *)d))) { + __android_log_print( + ANDROID_LOG_INFO, "YAPDroid", "OpenStream got %d ",sno); pop_text_stack(lvl); + if (sno < 0 || !Yap_ChDir(dirname((char *)d))) { *full = NULL; return -1; } LOCAL_PrologMode = UserMode; - - Yap_init_consult(consulted, pop_output_text_stack__(lvl, fl)); +*full = pop_output_text_stack__(lvl, fl); + Yap_init_consult(consulted,*full); RECOVER_MACHINE_REGS(); UNLOCK(GLOBAL_Stream[sno].streamlock); return sno; diff --git a/C/yap-args.c b/C/yap-args.c index ae4867f11..439ebfc64 100755 --- a/C/yap-args.c +++ b/C/yap-args.c @@ -153,22 +153,25 @@ const char *Yap_BINDIR, *Yap_ROOTDIR, *Yap_SHAREDIR, *Yap_LIBDIR, *Yap_DLLDIR, * recursive consulting. * * */ -static bool consult(const char *b_file USES_REGS) { +static bool load_file(const char *b_file USES_REGS) { Term t; int c_stream, osno, oactive; - Functor functor_query = Yap_MkFunctor(Yap_LookupAtom("?-"), 1); + + Functor functor_query = Yap_MkFunctor(Yap_LookupAtom("?-"), 1); Functor functor_command1 = Yap_MkFunctor(Yap_LookupAtom(":-"), 1); Functor functor_compile2 = Yap_MkFunctor(Yap_LookupAtom("c_compile"), 1); /* consult in C */ int lvl = push_text_stack(); char *full; - /* the consult mode does not matter here, really */ + /* the consult mode does not matter here, really */ if ((osno = Yap_CheckAlias(AtomLoopStream)) < 0) { osno = 0; } c_stream = YAP_InitConsult(YAP_BOOT_MODE, b_file, &full, &oactive); - if (c_stream < 0) { + __android_log_print( + ANDROID_LOG_INFO, "YAPDroid", "done init_ consult %s ",b_file); + if (c_stream < 0) { fprintf(stderr, "[ FATAL ERROR: could not open file %s ]\n", b_file); pop_text_stack(lvl); exit(1); @@ -177,6 +180,8 @@ static bool consult(const char *b_file USES_REGS) { pop_text_stack(lvl); return false; } + __android_log_print( + ANDROID_LOG_INFO, "YAPDroid", "do reset %s ",b_file); do { CACHE_REGS @@ -197,7 +202,7 @@ static bool consult(const char *b_file USES_REGS) { FunctorOfTerm(t) == functor_command1)) { t = ArgOfTerm(1, t); if (IsApplTerm(t) && FunctorOfTerm(t) == functor_compile2) { - consult(RepAtom(AtomOfTerm(ArgOfTerm(1, t)))->StrOfAE); + load_file(RepAtom(AtomOfTerm(ArgOfTerm(1, t)))->StrOfAE); Yap_ResetException(LOCAL_ActiveError); } else { YAP_RunGoalOnce(t); @@ -221,16 +226,82 @@ static bool consult(const char *b_file USES_REGS) { return true; } +static const char * EOLIST ="EOLINE"; + + + static bool is_dir( const char *path, const void *info) { + + if (Yap_isDirectory( path )) + return true; + char s[YAP_FILENAME_MAX + 1]; + Int i = strlen(path); + strncpy(s, path, YAP_FILENAME_MAX); + while (--i) { + if (Yap_dir_separator((int)path[i])) + break; + } + if (i == 0) { + s[0] = '.'; + i = 1; + } + s[i] = '\0'; + return + strcmp(info,s) == 0 || + Yap_isDirectory( s ); + } + + static bool is_file( const char *path, const void *info) { + + return Yap_Exists( path ); + } + + static bool is_wfile( const char *path, const void *info) { + + return true; + } + + typedef bool testf(const char *s, const void *info); + + /// /// -static const char *sel(bool dir, bool ok1, const char *s1, bool ok2, - const char *s2, ...) { - if (ok1 && s1) - return s1; - if (ok2) - return s2; - return NULL; -} + static const char *sel( + testf test, const void *info, const char *s1, ...) { + const char *fmt = s1; +va_list ap; + char *buf = malloc(FILENAME_MAX + 1); +__android_log_print( + ANDROID_LOG_INFO, "YAPDroid", "try %s", s1); + + va_start(ap, s1); + while (fmt != EOLIST) { + __android_log_print( ANDROID_LOG_INFO, "YAPDroid", "loop %s", fmt); + + if (fmt == NULL || fmt[0]=='\0') { + fmt = va_arg(ap, const char *); + continue; + } + strncpy(buf, fmt, FILENAME_MAX); // Yap_AbsoluteFile(fmt,true), FILENAME_MAX); + __android_log_print( ANDROID_LOG_INFO, "YAPDroid", "triyimh %s", buf); + if (test(buf,info)) { + __android_log_print( + ANDROID_LOG_INFO, "YAPDroid", "got %s", buf); + buf = realloc(buf, strlen(buf) + 1); + va_end(ap); + return buf; + } + __android_log_print( + ANDROID_LOG_INFO, "YAPDroid", "tried %s, failed", buf); + fmt = va_arg(ap, const char *); + } + + __android_log_print( + ANDROID_LOG_INFO, "YAPDroid", "failed search "); + va_end(ap); + free(buf); +return NULL; + } + static const char *join(const char *s0, const char *s1) { CACHE_REGS @@ -256,103 +327,130 @@ static void Yap_set_locations(YAP_init_args *iap) { // --_not useful in Android, WIN32; /// -- DESTDIR/ in Anaconda /// -- /usr/locall in most Unix style systems - Yap_ROOTDIR = sel(true, iap->ROOTDIR != NULL, iap->ROOTDIR, true, +#if 0 + Yap_ROOTDIR = sel( is_dir, NULL, + iap->ROOTDIR, + getenv("YAPROOTDIR"), #if __ANDROID__ - NULL, + "/", #else - join(getenv("DESTDIR"), YAP_ROOTDIR), + join(getenv("DESTDIR"), YAP_ROOTDIR), + join(getenv("DESTDIR"), join(getenv("ḦOME"),".local")), + join(getenv("DESTDIR"), "/usr/local"), + join(getenv("DESTDIR"), "/usr"), + join(getenv("DESTDIR"), "/opt"), #endif - false); - /// BINDIR: where the OS stores header files, namely libYap... - Yap_BINDIR = sel(true, iap->BINDIR != NULL, iap->BINDIR, true, -#if __ANDROID__ - NULL, -#else + EOLIST + ); + + /// BINDIR: where the OS stores header files, namely libYap... + Yap_BINDIR = sel( is_dir, Yap_ROOTDIR, iap->BINDIR, + getenv("YAPBINDIR"), +#if !defined(__ANDROID__) join(getenv("DESTDIR"), YAP_BINDIR), #endif - false); + join(Yap_ROOTDIR, "/bin"), + EOLIST); + /// LIBDIR: where the OS stores dynamic libraries, namely libYap... - Yap_LIBDIR = sel(true, iap->LIBDIR != NULL, iap->LIBDIR, true, -#if __ANDROID__ - NULL, -#else + Yap_LIBDIR = sel( is_dir, Yap_ROOTDIR, iap->LIBDIR, +#if !defined(__ANDROID__) join(getenv("DESTDIR"), YAP_LIBDIR), #endif - false); + join(Yap_ROOTDIR, "/lib"), + EOLIST); + /// DLLDIR: where libraries can find expicitely loaded DLLs - Yap_DLLDIR = sel(true, iap->DLLDIR != NULL, iap->DLLDIR, true, -#if __ANDROID__ - NULL, -#else - join(getenv("DESTDIR"), YAP_DLLDIR), + Yap_DLLDIR = sel(is_dir, Yap_LIBDIR, iap->DLLDIR, + getenv("YAPLIBDIR"), +#if !defined(__ANDROID__) + join(getenv("DESTDIR"), YAP_DLLDIR), + join(Yap_LIBDIR, "/yap"), #endif - false); + EOLIST); + /// INCLUDEDIR: where the OS stores header files, namely libYap... - Yap_INCLUDEDIR = sel(true, iap->INCLUDEDIR != NULL, iap->INCLUDEDIR, true, -#if __ANDROID__ - NULL, -#else - join(getenv("DESTDIR"), YAP_INCLUDEDIR), + Yap_INCLUDEDIR = sel(is_dir, Yap_ROOTDIR, iap->INCLUDEDIR, +#if !defined(__ANDROID__) + join(getenv("DESTDIR"), YAP_INCLUDEDIR), #endif - false); + join(Yap_ROOTDIR, "/include"), + EOLIST); + /// SHAREDIR: where OS & ARCH independent files live - Yap_SHAREDIR = sel(true, iap->SHAREDIR != NULL, iap->SHAREDIR, true, -#if __ANDROID__ - "/assets", -#else - join(getenv("DESTDIR"), YAP_SHAREDIR), + Yap_SHAREDIR = sel( is_dir, Yap_ROOTDIR, iap->SHAREDIR, + getenv("YAPSHAREDIR"), +#if !defined(__ANDROID__) + join(getenv("DESTDIR"), YAP_SHAREDIR), + join(Yap_ROOTDIR, "/share"), + "/assets", #endif - false); + join(Yap_ROOTDIR, "/files"), + EOLIST); /// PLDIR: where we can find Prolog files - Yap_PLDIR = sel(true, iap->PLDIR != NULL, iap->PLDIR, true, + Yap_PLDIR = sel( is_dir, Yap_SHAREDIR, iap->PLDIR, #if __ANDROID__ + YAP_PLDIR, "/assets/Yap", #else join(getenv("DESTDIR"), YAP_PLDIR), + join(Yap_SHAREDIR, "/Yap"), #endif - false); + EOLIST); /// ``COMMONSDIR: Prolog Commons - Yap_COMMONSDIR = sel(true, iap->COMMONSDIR != NULL, iap->COMMONSDIR, true, + Yap_COMMONSDIR = sel(is_dir, Yap_SHAREDIR, iap->COMMONSDIR, #if __ANDROID__ "/assets/PrologCommons", #else join(getenv("DESTDIR"), YAP_SHAREDIR "/PrologCommons"), + join(Yap_SHAREDIR, "PrologCommons"), #endif - false); + EOLIST); /// BOOTPLDIR: where we can find Prolog bootstrap files - Yap_BOOTSTRAP = sel(true, iap->BOOTSTRAP != NULL, iap->BOOTSTRAP, true, -#if __ANDROID__ - "/assets/Yap/pl/boot.yap", -#else - join(getenv("DESTDIR"), YAP_BOOTSTRAP), -#endif - false); + Yap_BOOTSTRAP = sel( is_file, NULL, iap->BOOTSTRAP, + YAP_BOOTSTRAP, + EOLIST); /// BOOTFILE: where we can find the core Prolog boot file - Yap_BOOTFILE = sel(false, iap->BOOTFILE != NULL, iap->BOOTFILE, true, + +const char * Yap_PLBOOTDIR = sel( is_dir, Yap_PLDIR, #if __ANDROID__ - "/assets/Yap/pl/boot.yap", + "/assets/Yap/pl", #else - join(getenv("DESTDIR"), YAP_BOOTFILE), + join(Yap_PLDIR, "/pl"), +#endif + EOLIST); + + Yap_BOOTFILE = sel( is_wfile, Yap_PLBOOTDIR, iap->BOOTFILE, +#if __ANDROID__ + "/assets/Yap/pl/boot.yap", +#else + join(Yap_PLBOOTDIR, "/boot.yap"), +#endif + EOLIST); #endif - false); /// STARTUP: where we can find the core Prolog bootstrap file Yap_OUTPUT_STARTUP = - sel(false, iap->OUTPUT_STARTUP != NULL, iap->OUTPUT_STARTUP, true, -#if __ANDROID__ - NULL, + sel( is_wfile, Yap_AbsoluteFile(".",false), iap->OUTPUT_STARTUP, +#if defined(__ANDROID__) +EOLIST, #else - join(getenv("DESTDIR"), YAP_OUTPUT_STARTUP), + YAP_OUTPUT_STARTUP, #endif - false); + "startup.yss", +EOLIST); + Yap_INPUT_STARTUP = - sel(false, iap->INPUT_STARTUP != NULL, iap->INPUT_STARTUP, true, + sel( is_wfile, Yap_DLLDIR, iap->INPUT_STARTUP, #if __ANDROID__ - NULL, +EOLIST, #else - join(getenv("DESTDIR"), YAP_INPUT_STARTUP), + join(getenv("DESTDIR"), YAP_INPUT_STARTUP), #endif - false); - if (Yap_ROOTDIR) + "startup.yss", + join(Yap_DLLDIR, "/startup.yss"), + EOLIST); + + if (Yap_ROOTDIR) setAtomicGlobalPrologFlag(HOME_FLAG, MkAtomTerm(Yap_LookupAtom(Yap_ROOTDIR))); if (Yap_PLDIR) @@ -461,17 +559,18 @@ X_API YAP_file_type_t Yap_InitDefaults(void *x, char *saved_state, int argc, LOCAL_TextBuffer = Yap_InitTextAllocator(); YAP_init_args *iap = x; memset(iap, 0, sizeof(YAP_init_args)); + iap->Argc = argc; + iap->Argv = argv; #if __ANDROID__ iap->boot_file_type = YAP_BOOT_PL; iap->INPUT_STARTUP = NULL; iap->assetManager = NULL; + return YAP_BOOT_PL; #else iap->boot_file_type = YAP_QLY; iap->INPUT_STARTUP = saved_state; -#endif - iap->Argc = argc; - iap->Argv = argv; return YAP_QLY; +#endif } /** @@ -1006,7 +1105,8 @@ X_API void YAP_Init(YAP_init_args *yap_init) { bool try_restore = yap_init->boot_file_type == YAP_QLY; bool do_bootstrap = yap_init->boot_file_type == YAP_BOOT_PL; struct ssz_t minfo; - + __android_log_print( + ANDROID_LOG_INFO, "YAPDroid", "start init "); if (YAP_initialized) /* ignore repeated calls to YAP_Init */ return; @@ -1039,16 +1139,20 @@ X_API void YAP_Init(YAP_init_args *yap_init) { Yap_ExecutionMode = yap_init->ExecutionMode; Yap_set_locations(yap_init); - if (do_bootstrap || !try_restore || + if (Yap_INPUT_STARTUP==NULL) + try_restore = false; + if (do_bootstrap || !try_restore || !Yap_SavedInfo(Yap_INPUT_STARTUP, &minfo.Trail, &minfo.Stack, &minfo.Heap)) { init_globals(yap_init); start_modules(); CurrentModule = PROLOG_MODULE; - TermEof = MkAtomTerm(Yap_LookupAtom("end_of_file")); + TermEof = MkAtomTerm(Yap_LookupAtom("end_of_file")); LOCAL_consult_level = -1; - consult(Yap_BOOTSTRAP PASS_REGS); + __android_log_print( + ANDROID_LOG_INFO, "YAPDroid", "init %s ", Yap_BOOTSTRAP); + load_file(Yap_BOOTSTRAP PASS_REGS); setAtomicGlobalPrologFlag(RESOURCE_DATABASE_FLAG, MkAtomTerm(Yap_LookupAtom(Yap_BOOTFILE))); setBooleanGlobalPrologFlag(SAVED_PROGRAM_FLAG, false); @@ -1056,6 +1160,8 @@ X_API void YAP_Init(YAP_init_args *yap_init) { if (yap_init->QuietMode) { setVerbosity(TermSilent); } + __android_log_print( + ANDROID_LOG_INFO, "YAPDroid", "restore %s ",Yap_INPUT_STARTUP ); Yap_Restore(Yap_INPUT_STARTUP); init_globals(yap_init); diff --git a/CMakeLists.txt b/CMakeLists.txt index fa886fc2e..9b31c68d8 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -320,6 +320,7 @@ set(YAP_ROOTDIR ${prefix}) # libdir defined above set(YAP_DATADIR ${CMAKE_INSTALL_FULL_DATADIR}) set(YAP_INCLUDEDIR ${CMAKE_INSTALL_FULL_INCLUDEDIR}/Yap) +set(YAP_BINDIR ${CMAKE_INSTALL_FULL_BINDIR}) set(YAP_LIBDIR ${CMAKE_INSTALL_FULL_LIBDIR}) set(YAP_DLLDIR ${CMAKE_INSTALL_FULL_LIBDIR}/Yap) set(YAP_PLDIR ${CMAKE_INSTALL_FULL_DATADIR}/Yap) diff --git a/CXX/yapq.hh b/CXX/yapq.hh index 7fcf764c0..c7a96a9f7 100644 --- a/CXX/yapq.hh +++ b/CXX/yapq.hh @@ -270,6 +270,8 @@ public: inline void setArgv(char **fl) { Argv = fl; }; inline char **getArgv() { return Argv; }; + + inline void setROOTDIR(char *fl) { ROOTDIR = fl; }; }; /** @@ -293,7 +295,14 @@ public: YAPEngine(YAPEngineArgs *cargs) { engine_args = cargs; // doInit(cargs->boot_file_type); + __android_log_print( + ANDROID_LOG_INFO, "YAPDroid", "start engine "); +#ifdef __ANDROID__ + doInit(YAP_BOOT_PL, cargs); + +#else doInit(YAP_QLY, cargs); +#endif }; /// construct a new engine, including aaccess to callbacks /// construct a new engine using argc/argv list of arguments YAPEngine(int argc, char *argv[], diff --git a/config.h.cmake b/config.h.cmake index f24df26d4..16547a3bc 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -2030,7 +2030,7 @@ significant byte first (like Motorola and SPARC, unlike Intel). */ /* name of Commons library */ #ifndef YAP_COMMONSDIR -#define YAP COMMONSDIR "${YAP_DATADIR}/PrologCommmons" +#define YAP_COMMONSDIR "${YAP_DATADIR}/PrologCommmons" #endif diff --git a/os/assets.c b/os/assets.c index ed1dac028..b19fb5b15 100644 --- a/os/assets.c +++ b/os/assets.c @@ -77,18 +77,20 @@ open_asset(VFS_t *me, const char *fname, const char *io_mode, int sno) { // AAssetDir *dp = AAssetManager_openDir( Yap_assetManager(), dirname(dir) ); // strcpy(dir, fname); // char *d = basename(dir); - am = AAssetManager_open(Yap_assetManager(), fname, mode); + am = AAssetManager_open(Yap_assetManager(), fname, io_mode); //if (am==NULL) // __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "failed open %s <%s>", fname, strerror(errno) ); - + __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "open %s <%s>", fname, io_mode); // while (dp) { // char *f = AAssetDir_getNextFileName(dp); -// __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "open %s <%s>", f, d); +// __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "open %s <%s>", fname, mode); // if (f && strcasecmp(d,f) == 0) { // // } // } if (!am) { + __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "failed %s <%s>", fname, io_mode); + return NULL; } // try not to use it as an asset @@ -111,7 +113,7 @@ open_asset(VFS_t *me, const char *fname, const char *io_mode, int sno) { st->vfs = NULL; st->vfs_handle = NULL; st->status = Seekable_Stream_f|Input_Stream_f; - return st; + return st->file; } else { // should be done, but if not GLOBAL_Stream[sno].vfs_handle = am; diff --git a/os/iopreds.c b/os/iopreds.c index f163624ff..dae2ecfd4 100644 --- a/os/iopreds.c +++ b/os/iopreds.c @@ -1135,7 +1135,7 @@ bool Yap_initStream(int sno, FILE *fd, Atom name, const char *io_mode, ANDROID_LOG_INFO, "YAPDroid", "init %s %s:%s stream <%d>", io_mode, CurrentModule == 0 ? "prolog" : RepAtom(AtomOfTerm(CurrentModule))->StrOfAE, - name, sno); + RepAtom(name)->StrOfAE, sno); if (io_mode == NULL) Yap_Error(PERMISSION_ERROR_NEW_ALIAS_FOR_STREAM, MkIntegerTerm(sno), "File opened with NULL Permissions"); @@ -1242,74 +1242,80 @@ static bool fill_stream(int sno, StreamDesc *st, Term tin, const char *io_mode, st->file = NULL; if (fname) { - if ((vfsp = vfs_owner(fname)) != NULL && - vfsp->open(vfsp, fname, io_mode, sno)) { - // read, write, append - user_name = st->user_name; - st->vfs = vfsp; - UNLOCK(st->streamlock); - } else { - st->file = fopen(fname, io_mode); - if (st->file == NULL) { - UNLOCK(st->streamlock); - if (errno == ENOENT && !strchr(io_mode, 'r')) { - PlIOError(EXISTENCE_ERROR_SOURCE_SINK, tin, "%s: %s", fname, - strerror(errno)); - } else { - PlIOError(PERMISSION_ERROR_OPEN_SOURCE_SINK, tin, "%s: %s", fname, - strerror(errno)); - } - } - st->vfs = NULL; - } - if (!st->file && !st->vfs) { - PlIOError(EXISTENCE_ERROR_SOURCE_SINK, tin, "%s", fname); - /* extract BACK info passed through the stream descriptor */ - return false; - } - } else if (IsApplTerm(tin)) { - Functor f = FunctorOfTerm(tin); - if (f == FunctorAtom || f == FunctorString || f == FunctorCodes1 || - f == FunctorCodes || f == FunctorChars1 || f == FunctorChars) { - if (strchr(io_mode, 'r')) { - return Yap_OpenBufWriteStream(PASS_REGS1); - } else { - int j = push_text_stack(); - const char *buf; + if ((vfsp = vfs_owner(fname)) != NULL) { + if (vfsp->open(vfsp, fname, io_mode, sno)) { + // read, write, append + user_name = st->user_name; + st->vfs = vfsp; + UNLOCK(st->streamlock); + __android_log_print( + ANDROID_LOG_INFO, "YAPDroid", "got %d ", sno); + } else { + UNLOCK(st->streamlock); + __android_log_print( + ANDROID_LOG_INFO, "YAPDroid", "failed %s ",fname); +return false; + } + } else { + st->file = fopen(fname, io_mode); + if (st->file == NULL) { + __android_log_print( + ANDROID_LOG_INFO, "YAPDroid", "failed %s ",fname); + UNLOCK(st->streamlock); + if (errno == ENOENT && !strchr(io_mode, 'r')) { + PlIOError(EXISTENCE_ERROR_SOURCE_SINK, tin, "%s: %s", fname, + strerror(errno)); + } else { + PlIOError(PERMISSION_ERROR_OPEN_SOURCE_SINK, tin, "%s: %s", fname, + strerror(errno)); + } + return false; + } - buf = Yap_TextTermToText(tin PASS_REGS); - if (!buf) { - pop_text_stack(j); - return false; - } - buf = pop_output_text_stack(j, buf); - Atom nat = Yap_LookupAtom(Yap_StrPrefix(buf, 32)); - sno = Yap_open_buf_read_stream(buf, strlen(buf) + 1, &LOCAL_encoding, - MEM_BUF_MALLOC, nat, - MkAtomTerm(NameOfFunctor(f))); - pop_text_stack(j); - return Yap_OpenBufWriteStream(PASS_REGS1); - } - } else if (!strcmp(RepAtom(NameOfFunctor(f))->StrOfAE, "popen")) { - const char *buf; - int i = push_text_stack(); - buf = Yap_TextTermToText(ArgOfTerm(1, tin) PASS_REGS); - if (buf == NULL) { - return false; } + } else if (IsApplTerm(tin)) { + Functor f = FunctorOfTerm(tin); + if (f == FunctorAtom || f == FunctorString || f == FunctorCodes1 || + f == FunctorCodes || f == FunctorChars1 || f == FunctorChars) { + if (strchr(io_mode, 'r')) { + return Yap_OpenBufWriteStream(PASS_REGS1); + } else { + int j = push_text_stack(); + const char *buf; + + buf = Yap_TextTermToText(tin PASS_REGS); + if (!buf) { + pop_text_stack(j); + return false; + } + buf = pop_output_text_stack(j, buf); + Atom nat = Yap_LookupAtom(Yap_StrPrefix(buf, 32)); + sno = Yap_open_buf_read_stream(buf, strlen(buf) + 1, &LOCAL_encoding, + MEM_BUF_MALLOC, nat, + MkAtomTerm(NameOfFunctor(f))); + pop_text_stack(j); + return Yap_OpenBufWriteStream(PASS_REGS1); + } + } else if (!strcmp(RepAtom(NameOfFunctor(f))->StrOfAE, "popen")) { + const char *buf; + int i = push_text_stack(); + buf = Yap_TextTermToText(ArgOfTerm(1, tin) PASS_REGS); + if (buf == NULL) { + return false; + } #if _WIN32 - st->file = _popen(buf, io_mode); + st->file = _popen(buf, io_mode); #else - st->file = popen(buf, io_mode); + st->file = popen(buf, io_mode); #endif - fname = "popen"; - user_name = tin; - st->status |= Popen_Stream_f; - pop_text_stack(i); - } else { - Yap_ThrowError(DOMAIN_ERROR_SOURCE_SINK, tin, "open"); - } - } + fname = "popen"; + user_name = tin; + st->status |= Popen_Stream_f; + pop_text_stack(i); + } else { + Yap_ThrowError(DOMAIN_ERROR_SOURCE_SINK, tin, "open"); + } + } if (!strchr(io_mode, 'b') && binary_file(fname)) { st->status |= Binary_Stream_f; } diff --git a/os/sysbits.c b/os/sysbits.c index a211b7ed6..1f0794b2b 100644 --- a/os/sysbits.c +++ b/os/sysbits.c @@ -355,7 +355,7 @@ bool Yap_ChDir(const char *path) { int lvl = push_text_stack(); const char *qpath = Yap_AbsoluteFile(path, true); - //__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "chdir %s", path); + __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "chdir %s", path); VFS_t *v; if ((v = vfs_owner(qpath))) { rc = v->chdir(v, (qpath)); From 705cb09f8d068243c531c9e751c96d287e93290b Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Fri, 14 Dec 2018 10:40:01 +0000 Subject: [PATCH 07/14] droid --- C/yap-args.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/C/yap-args.c b/C/yap-args.c index ae4867f11..dcb8a17af 100755 --- a/C/yap-args.c +++ b/C/yap-args.c @@ -463,15 +463,14 @@ X_API YAP_file_type_t Yap_InitDefaults(void *x, char *saved_state, int argc, memset(iap, 0, sizeof(YAP_init_args)); #if __ANDROID__ iap->boot_file_type = YAP_BOOT_PL; - iap->INPUT_STARTUP = NULL; - iap->assetManager = NULL; + return YAP_B #else iap->boot_file_type = YAP_QLY; iap->INPUT_STARTUP = saved_state; -#endif iap->Argc = argc; iap->Argv = argv; return YAP_QLY; +#endif } /** From 3fa4bfbcb2976123f7d332f7c13ecb0012c1e016 Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Fri, 14 Dec 2018 14:53:39 +0000 Subject: [PATCH 08/14] flow --- C/yap-args.c | 10 ++-- packages/myddas/pl/CMakeLists.txt | 10 ++-- .../yap_kernel/yap_ipython/prolog/jupyter.yap | 2 +- pl/attributes.yap | 2 +- pl/top.yap | 4 +- pl/undefined.yap | 53 +++++++++++-------- 6 files changed, 48 insertions(+), 33 deletions(-) diff --git a/C/yap-args.c b/C/yap-args.c index 439ebfc64..19fd28ee3 100755 --- a/C/yap-args.c +++ b/C/yap-args.c @@ -211,7 +211,7 @@ static bool load_file(const char *b_file USES_REGS) { YAP_CompileClause(t); } yap_error_descriptor_t *errd; - if ((errd = Yap_GetException(LOCAL_ActiveError))) { + if ((errd = Yap_GetException(LOCAL_ActiveError)) && (errd->errorNo != YAP_NO_ERROR)) { fprintf(stderr, "%s:%ld:0: Error %s %s Found\n", errd->errorFile, (long int)errd->errorLine, errd->classAsText, errd->errorAsText); } @@ -327,7 +327,6 @@ static void Yap_set_locations(YAP_init_args *iap) { // --_not useful in Android, WIN32; /// -- DESTDIR/ in Anaconda /// -- /usr/locall in most Unix style systems -#if 0 Yap_ROOTDIR = sel( is_dir, NULL, iap->ROOTDIR, getenv("YAPROOTDIR"), @@ -427,7 +426,6 @@ const char * Yap_PLBOOTDIR = sel( is_dir, Yap_PLDIR, join(Yap_PLBOOTDIR, "/boot.yap"), #endif EOLIST); -#endif /// STARTUP: where we can find the core Prolog bootstrap file Yap_OUTPUT_STARTUP = sel( is_wfile, Yap_AbsoluteFile(".",false), iap->OUTPUT_STARTUP, @@ -440,14 +438,16 @@ EOLIST, EOLIST); Yap_INPUT_STARTUP = - sel( is_wfile, Yap_DLLDIR, iap->INPUT_STARTUP, + sel( is_file, Yap_DLLDIR, iap->INPUT_STARTUP, + "startup.yss", #if __ANDROID__ EOLIST, #else join(getenv("DESTDIR"), YAP_INPUT_STARTUP), #endif - "startup.yss", join(Yap_DLLDIR, "/startup.yss"), + "/usr/local/lib/Yap/startup.yss", + "/usr/lib/Yap/startup.yss", EOLIST); if (Yap_ROOTDIR) diff --git a/packages/myddas/pl/CMakeLists.txt b/packages/myddas/pl/CMakeLists.txt index c3c71e0a5..09320f558 100644 --- a/packages/myddas/pl/CMakeLists.txt +++ b/packages/myddas/pl/CMakeLists.txt @@ -13,9 +13,13 @@ set(MYDDAS_DRIVERS ) set(MYDDAS_DBMS sqlite3 postgres odbc) +if (ANDROID) set (MYDDAS_PL_OUTDIR ${YAP_APP_DIR}/src/generated/assets/Yap ) + else() + set (MYDDAS_PL_OUTDIR ${CMAKE_CURRENT_BINARY_DIR}) + endif() get_property(MYDDAS_FLAGS GLOBAL PROPERTY COMPILE_DEFINITIONS) -foreach (filename in ${MYDDAS_YPP}) +foreach (filename ${MYDDAS_YPP}) get_filename_component(base ${filename} NAME_WE) set(base_abs ${MYDDAS_PL_OUTDIR}/${base}) set(outfile ${base_abs}.yap) @@ -24,7 +28,7 @@ foreach (filename in ${MYDDAS_YPP}) ) set_source_files_properties(outfile PROPERTIES GENERATED TRUE) endforeach () -foreach (dbms in ${MYDDAS_DBMS} ) +foreach (dbms ${MYDDAS_DBMS} ) set(outfile ${MYDDAS_PL_OUTDIR}/myddas_${dbms}.yap) execute_process( COMMAND ${CMAKE_C_COMPILER} -D${dbms} -x c -E -P -w ${CMAKE_CURRENT_SOURCE_DIR}/myddas_driver.ypp -o ${outfile} @@ -35,6 +39,6 @@ foreach (dbms in ${MYDDAS_DBMS} ) endforeach() set( MYDDAS_YAP ${CMAKE_CURRENT_SOURCE_DIR}/../sqlite3/sqlitest.yap ${CMAKE_CURRENT_SOURCE_DIR}/../sqlite3/chinook.db) -#add_to_group(MYDDAS_YAP pl_library ) + add_to_group(MYDDAS_YAP pl_library ) file(INSTALL ${MYDDAS_YAP} DESTINATION ${MYDDAS_PL_OUTDIR} ) diff --git a/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap b/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap index 4b4be4e88..09f21f89b 100644 --- a/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap +++ b/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap @@ -42,7 +42,7 @@ jupyter_cell(Caller, _, Line ) :- catch( python_query(Query,Line), error(A,B), - system_error(A,B) + (writeln(A,B),system_error(A,B)) ). restreams(call) :- diff --git a/pl/attributes.yap b/pl/attributes.yap index 1b53282b4..1a1ff8aec 100644 --- a/pl/attributes.yap +++ b/pl/attributes.yap @@ -165,7 +165,7 @@ prolog:copy_term(Term, Copy, Gs) :- -> Gs = [], copy_term(Term, Copy) ; findall(Term-Gs, - '$attributes':residuals_and_delete_attributes(Vs, Gs, Term), + attributes:residuals_and_delete_attributes(Vs, Gs, Term), [Copy-Gs]) ). diff --git a/pl/top.yap b/pl/top.yap index f509bd134..dd5a3149c 100644 --- a/pl/top.yap +++ b/pl/top.yap @@ -494,6 +494,7 @@ write_query_answer( Bindings ) :- '$write_goal_output'(G1, First, NG, Next, IG), '$write_vars_and_goals'(LG, Next, IG). + '$write_goal_output'(var([V|VL]), First, [var([V|VL])|L], next, L) :- !, ( First = first -> true ; format(user_error,',~n',[]) ), format(user_error,'~a',[V]), @@ -513,13 +514,12 @@ write_query_answer( Bindings ) :- G = [_|_], !, % dump on string first so that we can check whether we actually % had any output from the solver. - term_to_string( G, String), + format(string(String),Format,G), ( String == `` -> % we didn't IG = NG, First = Next ; % we did - ( First = first -> true ; format(user_error,',~n',[]) ), format(user_error, '~N~s', [String]), NG = [G|IG] ). diff --git a/pl/undefined.yap b/pl/undefined.yap index d2125e996..5c58a7f48 100644 --- a/pl/undefined.yap +++ b/pl/undefined.yap @@ -103,28 +103,39 @@ undefined_query(G0, M0, Cut) :- '$pred_exists'(unknown_predicate_handler(_,_,_,_), user), '$yap_strip_module'(M0:G0, EM0, GM0), user:unknown_predicate_handler(GM0,EM0,M1:G1), - !, - expand_goal(M1:G1, MG). -'$undefp_search'(MG, FMG) :- - expand_goal(MG, FMG). + !. +'$undefp_search'(M0:G0, M:G) :- +'$get_undefined_predicates'(G, M0, G0, M), !. :- abolish('$undefp'/2). % undef handler -'$undefp'([M0|G0], Action) :- +'$undefp'([M0|G0],_) :- % make sure we do not loop on undefined predicates - yap_flag( unknown, Action, fail), - '$stop_creeping'(Current), - % yap_flag( debug, Debug, false), - ( - '$undefp_search'(M0:G0, NM:NG), - ( M0 \== NM -> true ; G0 \== NG ), - NG \= fail - -> - yap_flag( unknown, _, Action), - % yap_flag( debug, _, Debug), + setup_and_call_cleanup( + ´$undef_set'(MG,Action,Debug,Current), + ´$search_def'(M0,G0,MG), + Port, + ´$undef_reset'(Port,Mo:GO,MG,Action,Debug,Current) + ). + +'$undef_set'(MG,Action,Debug,Current) :- + yap_flag( unknown, Action, fail), + yap_flag( debug, Debug, false), + '$stop_creeping'(Current). + +'$search_def'(M0,G0,NG:NM) :- +'$undefp_search'(M0:G0, NM:NG), +!, +'$pred_exists'(NG,NM). + + +´$undef_reset'(exit,_G0,NG:NM,Action,Debug,Current) :- + yap_flag( unknown, _, Action), + yap_flag( debug, _, Debug), + nonvar(NG) ( Current == true -> @@ -132,13 +143,13 @@ undefined_query(G0, M0, Cut) :- '$start_creep'([NM|NG], creep) ; '$execute0'(NG, NM) - ) - ; - yap_flag( unknown, _, Action), - '$handle_error'(Action,G0,M0) - ). + ). +´$undef_reset'(_,M0:G0,_NG,Action,Debug,_Current) :- + yap_flag( unknown, _, Action), + yap_flag( debug, _, Debug), +'$handle_error'(Action,G0,M0). -:- '$undefp_handler'('$undefp'(_,_), prolog). +:- '$undefp_handler'('$undefp'(_), prolog). /** @pred unknown(- _O_,+ _N_) From 37d5dcedc17b8c63cd9fa213454edb37816a130f Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Sun, 16 Dec 2018 02:21:54 +0000 Subject: [PATCH 09/14] yapi --- library/android.yap | 19 +++++++++++ os/readterm.c | 6 ++-- packages/python/swig/prolog/yapi.yap | 2 +- packages/python/swig/yap4py/yapi.py | 33 ++++++++++--------- .../python/yap_kernel/yap_ipython/yapi.py | 21 +++++++----- pl/boot.yap | 4 +-- pl/undefined.yap | 30 +++++++++-------- 7 files changed, 69 insertions(+), 46 deletions(-) create mode 100644 library/android.yap diff --git a/library/android.yap b/library/android.yap new file mode 100644 index 000000000..13e33bde3 --- /dev/null +++ b/library/android.yap @@ -0,0 +1,19 @@ +%:- start_low_level_trace. + +:- module(user). +:- yap_flag(verbose,normal). + +query( String ) :- + yap_flag(typein_module, Mod), + atomic_to_term( String, Goal, VarNames ), + query_to_answer( Mod:Goal, VarNames, Status, Bindings), + output( Bindings, Status) . + +output( Bindings, Status) :- + (Status == answer -> true ; + Status == exit ->true + ), + write_query_answer( Bindings ), + nl(user_error). + +%:- [sqlitest]. \ No newline at end of file diff --git a/os/readterm.c b/os/readterm.c index 74d5e419b..4a12db042 100644 --- a/os/readterm.c +++ b/os/readterm.c @@ -376,10 +376,10 @@ static Term syntax_error(TokEntry *errtok, int sno, Term cmod, Int newpos, bool TokEntry *tok = LOCAL_tokptr; Int start_line = tok->TokLine; Int err_line = errtok->TokLine; - Int end_line = GetCurInpLine(GLOBAL_Stream + sno); - Int startpos = tok->TokPos; + Int startpos = tok->TokPos; Int errpos = errtok->TokPos; - Int endpos = GetCurInpPos(GLOBAL_Stream + sno); + Int end_line = GetCurInpLine(GLOBAL_Stream + sno); + Int endpos = GetCurInpPos(GLOBAL_Stream + sno); Yap_local.ActiveError->errorNo = SYNTAX_ERROR; Yap_local.ActiveError->parserFirstLine = start_line; diff --git a/packages/python/swig/prolog/yapi.yap b/packages/python/swig/prolog/yapi.yap index 5cd1303c1..607d87fcb 100644 --- a/packages/python/swig/prolog/yapi.yap +++ b/packages/python/swig/prolog/yapi.yap @@ -73,7 +73,7 @@ python_query( Caller, String ) :- query_to_answer( Goal, VarNames, Status, Bindings), Caller.port := Status, write_query_answer( Bindings ), - nl(user_error), + nl(user_error), maplist(in_dict(Caller.answer, Bindings), Bindings). /** diff --git a/packages/python/swig/yap4py/yapi.py b/packages/python/swig/yap4py/yapi.py index faba19c8c..3763ad04b 100644 --- a/packages/python/swig/yap4py/yapi.py +++ b/packages/python/swig/yap4py/yapi.py @@ -78,16 +78,20 @@ class Query (YAPQuery): super().__init__(g) self.engine = engine self.port = "call" - self.bindings = None - self.answer = {} def __iter__(self): return self + def done(self): + return self.port == "fail" or self.port == "exit" + def __next__(self): - if self.port == "fail": - raise IndexError() - return self.next() + self.answer = {} + if self.port == "fail" or self.port == "exit": + raise StopIteration() + if self.next(): + return self.answer + raise StopIteration() def name( name, arity): try: @@ -141,7 +145,7 @@ class YAPShell: # # 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 - import pdb; pdb.set_trace() + # import pdb; pdb.set_trace() # #pdb.set_trace() # atom match either symbols, or if no symbol exists, sttrings, In this case # variable names should match strings @@ -151,14 +155,13 @@ class YAPShell: # return try: engine = self.engine - bindings = [] + bindings = [] loop = False - g = python_query(self, query) - self.q = Query( engine, g ) - while self.q.next(): - bindings += [self.q.answer] - if self.q.port == "exit": - break + q = Query( engine, python_query( engine, query) ) + for answer in q: + bindings += [answer] + if g.done(): + return bindings if loop: continue s = input("more(;), all(*), no(\\n), python(#)? ").lstrip() @@ -177,10 +180,8 @@ class YAPShell: if self.q: self.q.close() self.q = None - if bindings: - return True,bindings print("No (more) answers") - return False, None + return bindings except Exception as e: if not self.q: return False, None diff --git a/packages/python/yap_kernel/yap_ipython/yapi.py b/packages/python/yap_kernel/yap_ipython/yapi.py index a735623ef..10a996c2e 100644 --- a/packages/python/yap_kernel/yap_ipython/yapi.py +++ b/packages/python/yap_kernel/yap_ipython/yapi.py @@ -550,7 +550,7 @@ class YAPRun(InteractiveShell): self.yapeng.mgoal(errors(self,text),"user",True) return self.errors - def jupyter_query(self, s): + def prolog(self, s): # # construct a self.queryuery from a one-line string # self.query is opaque to Python @@ -590,7 +590,7 @@ class YAPRun(InteractiveShell): if found: sys.stderr.write('Completed, with '+str(self.answers)+'\n') result.result = self.answers - return result + return result.results except Exception as e: sys.stderr.write('Exception '+str(e)+'in query '+ str(self.query)+ @@ -736,7 +736,7 @@ class YAPRun(InteractiveShell): # run the new command using the given tracer # # tracer.runfunc(f,self,cell,state) - self.jupyter_query( cell ) + self.prolog( cell ) # state = tracer.runfunc(jupyter_query( self, cell ) ) self.shell.last_execution_succeeded = True result.result = [] @@ -814,12 +814,15 @@ class YAPRun(InteractiveShell): If the line terminates on a `*/` or starts on a `%` we assume the line is a comment. """ - s0 = s.rstrip(' \n\t\i') - [program,x,query] = s0.rpartition('\n') - if query[-1] == '.': - return s,'',False,0 - (query, _,loop, sols) = self.clean_end(query) - return (program, query, loop, sols) + try: + s0 = s.rstrip(' \n\t\i') + [program,x,query] = s0.rpartition('\n') + if query[-1] == '.': + return s,'',False,0 + (query, _,loop, sols) = self.clean_end(query) + return (program, query, loop, sols) + except: + return (s,'',true,1) # global #globals = {} diff --git a/pl/boot.yap b/pl/boot.yap index e57399718..815604cc3 100644 --- a/pl/boot.yap +++ b/pl/boot.yap @@ -476,9 +476,7 @@ If this hook preodicate succeeds it must instantiate the _Action_ argument to t :- ensure_loaded('../pl/pathconf.yap'). -:- current_prolog_fkag(android,true), ensure_loaded('../pl/android.yap'). - - +:- current_prolog_flag(android,true), ensure_loaded('../android.yap'). :- set_prolog_flag(unknown,error). diff --git a/pl/undefined.yap b/pl/undefined.yap index 5c58a7f48..fd2d14731 100644 --- a/pl/undefined.yap +++ b/pl/undefined.yap @@ -102,7 +102,7 @@ undefined_query(G0, M0, Cut) :- '$undefp_search'(M0:G0, MG) :- '$pred_exists'(unknown_predicate_handler(_,_,_,_), user), '$yap_strip_module'(M0:G0, EM0, GM0), - user:unknown_predicate_handler(GM0,EM0,M1:G1), + user:unknown_predicate_handler(GM0,EM0,MG), !. '$undefp_search'(M0:G0, M:G) :- '$get_undefined_predicates'(G, M0, G0, M), !. @@ -113,29 +113,30 @@ undefined_query(G0, M0, Cut) :- % undef handler '$undefp'([M0|G0],_) :- +start_low_level_trace, % make sure we do not loop on undefined predicates - setup_and_call_cleanup( - ´$undef_set'(MG,Action,Debug,Current), - ´$search_def'(M0,G0,MG), + setup_call_catcher_cleanup( + '$undef_set'(Action,Debug,Current), + '$search_def'(M0,G0,MG), Port, - ´$undef_reset'(Port,Mo:GO,MG,Action,Debug,Current) + '$undef_reset'(Port,M0:G0,MG,Action,Debug,Current) ). -'$undef_set'(MG,Action,Debug,Current) :- +'$undef_set'(Action,Debug,Current) :- yap_flag( unknown, Action, fail), yap_flag( debug, Debug, false), '$stop_creeping'(Current). '$search_def'(M0,G0,NG:NM) :- -'$undefp_search'(M0:G0, NM:NG), -!, -'$pred_exists'(NG,NM). + '$undefp_search'(M0:G0, NM:NG), + !, + '$pred_exists'(NG,NM). - -´$undef_reset'(exit,_G0,NG:NM,Action,Debug,Current) :- +'$undef_reset'(exit,_G0,NG:NM,Action,Debug,Current) :- yap_flag( unknown, _, Action), yap_flag( debug, _, Debug), - nonvar(NG) + nonvar(NG), + nonvar(NM), ( Current == true -> @@ -144,12 +145,13 @@ undefined_query(G0, M0, Cut) :- ; '$execute0'(NG, NM) ). -´$undef_reset'(_,M0:G0,_NG,Action,Debug,_Current) :- +'$undef_reset'(_,M0:G0,_NG,Action,Debug,_Current) :- yap_flag( unknown, _, Action), yap_flag( debug, _, Debug), +'$start_creep'([prolog|true], creep), '$handle_error'(Action,G0,M0). -:- '$undefp_handler'('$undefp'(_), prolog). +:- '$undefp_handler'('$undefp'(_,_), prolog). /** @pred unknown(- _O_,+ _N_) From 5b96e59311676b3447709e39e37d5149e9743f1c Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Sun, 16 Dec 2018 02:25:48 +0000 Subject: [PATCH 10/14] yapi --- docs/CMakeLists.txt | 202 +++++++++--------- docs/md/INSTALL.md | 22 +- docs/md/programming.md | 22 +- docs/md/run.md | 6 +- docs/md/swi.md | 10 +- docs/md/yap.md | 2 +- misc/editors/prolog.js | 2 +- packages/python/swig/prolog/yapi.yap | 2 +- .../python/yap_kernel/yap_ipython/yapi.py | 6 +- pl/top.yap | 2 +- 10 files changed, 136 insertions(+), 140 deletions(-) diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 455106db6..49cd21179 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -1,16 +1,15 @@ - if (WITH_DOCS) - set (TOP_DIR YES) + set (TOP_DIR YES) -set(DOCS_SOURCE_DIR ${CMAKE_SOURCE_DIR}/docs) + set(DOCS_SOURCE_DIR ${CMAKE_SOURCE_DIR}/docs) -SET (CMAKE_HTML_EXTRA_) + SET (CMAKE_HTML_EXTRA_) -SET( EXT - ${DOCS_SOURCE_DIR}/custom/application.js - ${DOCS_SOURCE_DIR}/custom/assets + SET( EXT + ${DOCS_SOURCE_DIR}/custom/application.js + ${DOCS_SOURCE_DIR}/custom/assets ${DOCS_SOURCE_DIR}/custom/bootstrap.min.css ${DOCS_SOURCE_DIR}/custom/bootstrap.min.js ${DOCS_SOURCE_DIR}/custom/customdoxygen.css @@ -27,123 +26,122 @@ SET( EXT ${DOCS_SOURCE_DIR}/custom/yap.css ) - foreach(i ${CMAKE_HTML_EXTRA_}) - string(APPEND CMAKE_HTML_EXTRA ${i} " ") - endforeach(i ${CMAKE_HTML_EXTRA_}) + foreach(i ${CMAKE_HTML_EXTRA_}) + string(APPEND CMAKE_HTML_EXTRA ${i} " ") + endforeach(i ${CMAKE_HTML_EXTRA_}) -set(DOC_DIRS_EXCLUDE_ -${CMAKE_SOURCE_DIR}/build -${CMAKE_SOURCE_DIR}/Debug -${CMAKE_SOURCE_DIR}/packages/jpl -${CMAKE_SOURCE_DIR}/packages/swi -${CMAKE_SOURCE_DIR}/packages/Problog/problog_examples -${CMAKE_SOURCE_DIR}/packages/myddas/sqlite3/src -${CMAKE_SOURCE_DIR}/packages/gecode/6.0.1 -${CMAKE_SOURCE_DIR}/packages/gecode/6.0.0 -${CMAKE_SOURCE_DIR}/packages/gecode/5.1.0 -${CMAKE_SOURCE_DIR}/packages/gecode/5.0.0 -${CMAKE_SOURCE_DIR}/packages/gecode/4.4.0 -${CMAKE_SOURCE_DIR}/packages/gecode/4.2.1 -${CMAKE_SOURCE_DIR}/packages/gecode/4.2.0 -${CMAKE_SOURCE_DIR}/packages/gecode/4.0.0 -${CMAKE_SOURCE_DIR}/packages/gecode/3.7.3 -${CMAKE_SOURCE_DIR}/packages/gecode/3.7.2 -${CMAKE_SOURCE_DIR}/packages/gecode/3.7.1 -${CMAKE_SOURCE_DIR}/packages/gecode/3.7.0 -${CMAKE_SOURCE_DIR}/packages/gecode/3.6.0 -${CMAKE_SOURCE_DIR}/packages/gecode/dev -${CMAKE_SOURCE_DIR}/packages/cplint -${CMAKE_SOURCE_DIR}/packages/CLPBN/examples -${CMAKE_SOURCE_DIR}/packages/CLPBN/horus -${CMAKE_SOURCE_DIR}/packages/cuda -${CMAKE_SOURCE_DIR}/packages/prosqlite -${CMAKE_SOURCE_DIR}/packages/pyswip -${CMAKE_SOURCE_DIR}/packages/python/yap_kernel -${CMAKE_SOURCE_DIR}/packages/python/swig -${CMAKE_SOURCE_DIR}/packages/yap-lbfgs/liblbfgs-1.10 -${CMAKE_SOURCE_DIR}/packages/swi-minisat2 -${CMAKE_SOURCE_DIR}/library/dialect/swi/os -) + set(DOC_DIRS_EXCLUDE_ + ${CMAKE_SOURCE_DIR}/build + ${CMAKE_SOURCE_DIR}/Debug + ${CMAKE_SOURCE_DIR}/packages/jpl + ${CMAKE_SOURCE_DIR}/packages/swi + ${CMAKE_SOURCE_DIR}/packages/Problog/problog_examples + ${CMAKE_SOURCE_DIR}/packages/myddas/sqlite3/src + ${CMAKE_SOURCE_DIR}/packages/gecode/6.0.1 + ${CMAKE_SOURCE_DIR}/packages/gecode/6.0.0 + ${CMAKE_SOURCE_DIR}/packages/gecode/5.1.0 + ${CMAKE_SOURCE_DIR}/packages/gecode/5.0.0 + ${CMAKE_SOURCE_DIR}/packages/gecode/4.4.0 + ${CMAKE_SOURCE_DIR}/packages/gecode/4.2.1 + ${CMAKE_SOURCE_DIR}/packages/gecode/4.2.0 + ${CMAKE_SOURCE_DIR}/packages/gecode/4.0.0 + ${CMAKE_SOURCE_DIR}/packages/gecode/3.7.3 + ${CMAKE_SOURCE_DIR}/packages/gecode/3.7.2 + ${CMAKE_SOURCE_DIR}/packages/gecode/3.7.1 + ${CMAKE_SOURCE_DIR}/packages/gecode/3.7.0 + ${CMAKE_SOURCE_DIR}/packages/gecode/3.6.0 + ${CMAKE_SOURCE_DIR}/packages/gecode/dev + ${CMAKE_SOURCE_DIR}/packages/cplint + ${CMAKE_SOURCE_DIR}/packages/CLPBN/examples + ${CMAKE_SOURCE_DIR}/packages/CLPBN/horus + ${CMAKE_SOURCE_DIR}/packages/cuda + ${CMAKE_SOURCE_DIR}/packages/prosqlite + ${CMAKE_SOURCE_DIR}/packages/pyswip + ${CMAKE_SOURCE_DIR}/packages/python/yap_kernel + ${CMAKE_SOURCE_DIR}/packages/python/swig + ${CMAKE_SOURCE_DIR}/packages/yap-lbfgs/liblbfgs-1.10 + ${CMAKE_SOURCE_DIR}/packages/swi-minisat2 + ${CMAKE_SOURCE_DIR}/library/dialect/swi/os + ) -set(DOCS_EXCLUDE_ -${CMAKE_SOURCE_DIR}/C/traced_absmi_insts.h -${CMAKE_SOURCE_DIR}/H/globals.h -${CMAKE_SOURCE_DIR}/OPTYap/locks_alpha_funcs.h -${CMAKE_SOURCE_DIR}/OPTYap/locks_mips_funcs.h -${CMAKE_SOURCE_DIR}/OPTYap/locks_sparc.h -${CMAKE_SOURCE_DIR}/*/bprolog/* - ${CMAKE_SOURCE_DIR}/*/prism/* - ${CMAKE_SOURCE_DIR}/*/gecode/[345]* - ${CMAKE_SOURCE_DIR}/packages/gecode/gecode3_yap.cc - ${CMAKE_SOURCE_DIR}/packages/gecode/gecode4_yap.cc - ${CMAKE_SOURCE_DIR}/packages/gecode/gecode5_yap.cc - ${CMAKE_SOURCE_DIR}/packages/gecode/gecode3.yap - ${CMAKE_SOURCE_DIR}/packages/gecode/gecode4.yap - ${CMAKE_SOURCE_DIR}/packages/gecode/gecode5.yap - ${CMAKE_SOURCE_DIR}/packages/gecode/gecode3_yap_hand_written.yap - ${CMAKE_SOURCE_DIR}/packages/gecode/gecode4_yap_hand_written.yap - ${CMAKE_SOURCE_DIR}/packages/gecode/gecode5_yap_hand_written.yap - */CMakeFiles/* -) + set(DOCS_EXCLUDE_ + ${CMAKE_SOURCE_DIR}/C/traced_absmi_insts.h + ${CMAKE_SOURCE_DIR}/H/globals.h + ${CMAKE_SOURCE_DIR}/OPTYap/locks_alpha_funcs.h + ${CMAKE_SOURCE_DIR}/OPTYap/locks_mips_funcs.h + ${CMAKE_SOURCE_DIR}/OPTYap/locks_sparc.h + ${CMAKE_SOURCE_DIR}/*/bprolog/* + ${CMAKE_SOURCE_DIR}/*/prism/* + ${CMAKE_SOURCE_DIR}/*/gecode/[345]* + ${CMAKE_SOURCE_DIR}/packages/gecode/gecode3_yap.cc + ${CMAKE_SOURCE_DIR}/packages/gecode/gecode4_yap.cc + ${CMAKE_SOURCE_DIR}/packages/gecode/gecode5_yap.cc + ${CMAKE_SOURCE_DIR}/packages/gecode/gecode3.yap + ${CMAKE_SOURCE_DIR}/packages/gecode/gecode4.yap + ${CMAKE_SOURCE_DIR}/packages/gecode/gecode5.yap + ${CMAKE_SOURCE_DIR}/packages/gecode/gecode3_yap_hand_written.yap + ${CMAKE_SOURCE_DIR}/packages/gecode/gecode4_yap_hand_written.yap + ${CMAKE_SOURCE_DIR}/packages/gecode/gecode5_yap_hand_written.yap + */CMakeFiles/* + ) -foreach(i ${DOCS_EXCLUDE_}) - string(APPEND DOCS_EXCLUDE ${i} " ") -endforeach(i ${DOCS_EXCLUDE_}) + foreach(i ${DOCS_EXCLUDE_}) + string(APPEND DOCS_EXCLUDE ${i} " ") + endforeach(i ${DOCS_EXCLUDE_}) -foreach(i ${DOCS_DIR_EXCLUDE_}) - string(APPEND DOCS_DIR_EXCLUDE ${i} " ") -endforeach(i ${DOCS_DIR_EXCLUDE_}) + foreach(i ${DOCS_DIR_EXCLUDE_}) + string(APPEND DOCS_DIR_EXCLUDE ${i} " ") + endforeach(i ${DOCS_DIR_EXCLUDE_}) -# add a target to generate API documentation with Doxygen + # add a target to generate API documentation with Doxygen - set(doxyfile_in ${CMAKE_SOURCE_DIR}/docs/Doxyfile.in) + set(doxyfile_in ${CMAKE_SOURCE_DIR}/docs/Doxyfile.in) - add_subdirectory(../packages/raptor/doc ${CMAKE_BINARY_DIR}/packages/raptor/doc) + add_subdirectory(../packages/raptor/doc ${CMAKE_BINARY_DIR}/packages/raptor/doc) - SET(DOC_INPUT_FILES_ - ${CMAKE_SOURCE_DIR}/docs/md - ${CMAKE_SOURCE_DIR}/pl - ${CMAKE_SOURCE_DIR}/packages/ProbLog - ${CMAKE_SOURCE_DIR}/CXX - ${CMAKE_SOURCE_DIR}/OPTYap - ${CMAKE_SOURCE_DIR}/C - ${CMAKE_SOURCE_DIR}/H - ${CMAKE_SOURCE_DIR}/include - ${CMAKE_SOURCE_DIR}/os - ${CMAKE_SOURCE_DIR}/library - ${CMAKE_SOURCE_DIR}/swi/library - #${CMAKE_SOURCE_DIR}/packages - ${CMAKE_SOURCE_DIR}/BEAM - ) + SET(DOC_INPUT_FILES_ + ${CMAKE_SOURCE_DIR}/docs/md + ${CMAKE_SOURCE_DIR}/pl + ${CMAKE_SOURCE_DIR}/CXX + ${CMAKE_SOURCE_DIR}/OPTYap + ${CMAKE_SOURCE_DIR}/C + ${CMAKE_SOURCE_DIR}/H + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/os + ${CMAKE_SOURCE_DIR}/library + ${CMAKE_SOURCE_DIR}/swi/library + ${CMAKE_SOURCE_DIR}/packages + ${CMAKE_SOURCE_DIR}/BEAM + ) -foreach(i ${DOC_INPUT_FILES_}) + foreach(i ${DOC_INPUT_FILES_}) - string(APPEND DOC_INPUT_FILES ${i} " ") -endforeach(i ${DOC_INPUT_FILES_}) + string(APPEND DOC_INPUT_FILES ${i} " ") + endforeach(i ${DOC_INPUT_FILES_}) - set(doxyfile ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) - configure_file(${doxyfile_in} ${doxyfile} @ONLY) + set(doxyfile ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) + configure_file(${doxyfile_in} ${doxyfile} @ONLY) - configure_file(${CMAKE_SOURCE_DIR}/docs/source/conf.py.in source/conf.py) - configure_file(${CMAKE_SOURCE_DIR}/docs/source/index.rst source/index.rst) - -add_custom_target(docs - COMMAND ${DOXYGEN_EXECUTABLE} ${doxyfile} - ) + configure_file(${CMAKE_SOURCE_DIR}/docs/source/conf.py.in source/conf.py) + configure_file(${CMAKE_SOURCE_DIR}/docs/source/index.rst source/index.rst) + + add_custom_target(docs + COMMAND ${DOXYGEN_EXECUTABLE} ${doxyfile} + ) - if (EXISTS ${CMAKE_CURRENT_BINARY_DIR}/html) - install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION ${docdir}) + if (EXISTS ${CMAKE_CURRENT_BINARY_DIR}/html) + install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION ${docdir}) - install(FILES ${CODES} DESTINATION ${docdir}) - endif() + install(FILES ${CODES} DESTINATION ${docdir}) + endif() endif() diff --git a/docs/md/INSTALL.md b/docs/md/INSTALL.md index d2042b8d8..5d28f4063 100644 --- a/docs/md/INSTALL.md +++ b/docs/md/INSTALL.md @@ -5,7 +5,7 @@ This text includes instructions to download and install YAP. [TOC] -## Downloading YAP {#Download} +@section Download Downloading YAP The latest development version of Yap-6 is available source-only through GIT repositories. The main reference repository is at @@ -26,7 +26,7 @@ The first argument is the repository, the last argument is the (optional) target There are a variety of graphical interfaces to `git`, including GitHub's own [GitHub Desktop](https://desktop.github.com/) that supports Microsoft Windows and Apple OSX. A list with GUI applications, editor integration, and much more can be found at the [git Wiki](https://git.wiki.kernel.org/index.php/InterfacesFrontendsAndTools), -### Download Options +@subsection DownloadOptions Download Options It may be useful to know: @@ -43,8 +43,8 @@ to only include the last `XX` commits. including [doxygen-yap](https://github.com/vscosta/doxygen-yap), a version of doxygen adapted to Prolog that was used to generate these documents. - -## CompilingYAP Compiling YAP + +@section CompilingYAP Compiling YAP YAP-6.3.4 is a [cmake](www.cmake.org) based @@ -53,7 +53,7 @@ generate Makefiles, Ninja, Apple's XCode, VisualStudio and ANdroid Studio, and because it includes packaging suppport, The steps required to install core YAP under `cmake` are presented in detail next. -### Compilation The compiler +@subsubsection Compilation The compiler *Status as of early 2017* @@ -70,7 +70,7 @@ to install core YAP under `cmake` are presented in detail next. YAP compiles cleanly under cross-compilers, and we have used the crosss-compilation system [mxe](http://mxe.cc/) system with good results. -### cmake +@subsection cmake cmake All Linux and BSD distributions include `cmake`, so does [Homebrew](https://brew.sh/) @@ -85,7 +85,7 @@ the [CMake site](https://www.cmake.org). If you have an older Linux you may need to compile from source, available at GitHub. -### Ensure that you have other necessary packages installed: +@subsection extrapacks Ensure that you have other necessary packages installed: + YAP requires [gmp]{https://gmplib.org/} for infinite precision integer and rational. Please ensure the development pacakage @@ -106,7 +106,7 @@ available at GitHub. + make sure to install Python-3, and not Python-2, -### Compiling Compile and Install +@subsection Compiling2 Compile and Install 1: Create a directory, say `Build` and `cd` to the directory (`cd Build`). *YAP should not be compiled at its rootxo directory, some packages do not allow for that. @@ -120,7 +120,7 @@ available at GitHub. 5: If you feel satisfied with the result, do `make install`. * In most systems you will need to be superuser in order to do `make install` and `make info` on the standard directories. -#### Tuning the Functionality of YAP +@subsection TuningYAP the Functionality of YAP By default, YAP supports tabling, depth first search, and most features found in modern Prologs. In some cases, you may want to suport extra features, or reduce system size. @@ -181,7 +181,7 @@ You can also use `xcodebuild` from the command line. Bext follow instructions to fully compile YAP: -### Compilation Notes for OSX/Brew +@subsection TuningBrew Compilation Notes for OSX/Brew Next follows a detailed description of a full install of YAP, including all the packages that YAP can use: @@ -214,7 +214,7 @@ brew install cudd cmake -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl .. ~~~~~ -### Compilation Notes for Android +@sususbsection TuningDroid Compilation Notes for Android Next we present the compilation process for Android. The environment is an OSX, but steps should be similar for Linux machines. We assume you have downloaded both the Android NDK and the Android SDK. diff --git a/docs/md/programming.md b/docs/md/programming.md index 76a9d513d..638207058 100644 --- a/docs/md/programming.md +++ b/docs/md/programming.md @@ -1,23 +1,21 @@ -@defgroup YAPProgramming Programming in YAP - -@{ +Programming in YAP {#YAPProgramming} +================= [TOC] -@} @defgroup load_files Loading and Organizing YAP Programs - +@ingroup YAPProgramming @{ We present the main predicates and directives available to load files and to control the Prolog environment. - -[TOC] + [TOC] @} -@defgroup YAPModules The YAP Module system +@section YAPModules The YAP Module system +@ingroup YAPProgramming @{ The YAP module system is based on the Quintus/SISCtus module @@ -57,7 +55,7 @@ We present the main predicates and directives available to load it starts consulting a file, and resets it at the end. One can set the type-in module permanently by using the built-in `module/1`. - ### Explicit Naming {#ExplicitNaming} + @subsection ExplicitNaming Explicit Naming The module system allows one to _explicitly_ specify the source mode for a clause by prefixing a clause with its module, say: @@ -245,9 +243,9 @@ We present the main predicates and directives available to load The state of the module system after this error is undefined. - ### Built-In predicates {#ModuleBuiltins) +@subsection ModuleBuiltins Built-In predicates - @\pred module(+ M:atom,+ L:list ) is directive + @pred module(+ M:atom,+ L:list ) is directive the current file defines module _M_ with exports _L_. The list may include + predicate indicators @@ -337,7 +335,7 @@ We present the main predicates and directives available to load + library( +File ) a library file to import into the current module. - + + hide( +Opt) if _Opt_ is `false`, keep source code for current module, if `true`, disable. diff --git a/docs/md/run.md b/docs/md/run.md index d382dc6be..ed32ea1a2 100644 --- a/docs/md/run.md +++ b/docs/md/run.md @@ -7,8 +7,8 @@ We next describe how to invoke YAP in Unix systems. [TOC] -Running YAP Interactively {#Running_YAP_Interactively} --------------------------- +@section Running_YAP_Interactively Running YAP Interactively + Most often you will want to use YAP in interactive mode. Assuming that YAP is in the user's search path, the top-level can be invoked under @@ -87,7 +87,7 @@ the environment variable YAPBINDIR. + YAP will try to find library files from the YAPSHAREDIR/library directory. -Running Prolog Files {#Running_Prolog_Files} +@section RunningScripts Running Prolog Files -------------------- YAP can also be used to run Prolog files as scripts, at least in diff --git a/docs/md/swi.md b/docs/md/swi.md index c4d81dcbe..5f085f7f3 100644 --- a/docs/md/swi.md +++ b/docs/md/swi.md @@ -56,7 +56,7 @@ Please do refer to the SWI-Prolog home page: for more information on SWI-Prolog and the SWI packages. -#### Compatibility with the C-Prolog interpreter {#ChYProlog} +@section ChYProlog Compatibility with the C-Prolog interpreter YAP was designed so that most C-Prolog programs should run under YAP @@ -97,8 +97,7 @@ or by using: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Compatibility with the Quintus and SICStus Prolog systems ---------------------------------------------------------- +@section QuiSics Compatibility with the Quintus and SICStus Prolog systems The Quintus Prolog system was the first Prolog compiler to use Warren's Abstract Machine. This system was very influential in the Prolog @@ -130,8 +129,9 @@ SICStus Prolog or SWI-Prolog. + This list is incomplete. -Compatibility with the ISO Prolog standard ------------------------------------------- + +@section ISOCompat Compatibility with the ISO Prolog standard + The Prolog standard was developed by ISO/IEC JTC1/SC22/WG17, the international standardization working group for the programming language diff --git a/docs/md/yap.md b/docs/md/yap.md index 364594002..d589d4a4d 100644 --- a/docs/md/yap.md +++ b/docs/md/yap.md @@ -7,7 +7,7 @@ NOTE: this version of YAP is still experimental, documentation may be missing or out of date. -## Introduction + @section Introduction Introduction This document provides User information on version 6.3.4 of YAP (Yet Another Prolog). The YAP Prolog System is a diff --git a/misc/editors/prolog.js b/misc/editors/prolog.js index 72bd11c26..7f5d4efc3 100644 --- a/misc/editors/prolog.js +++ b/misc/editors/prolog.js @@ -749,7 +749,7 @@ IfTrue CodeMirror.defineOption( "prologKeys", true, function(cm, editor, prev) { document = cm.getDoc(); - if (nnprev && prev != CodeMirror.Init) + if (prev && prev != CodeMirror.Init) cm.removeKeyMap("prolog"); if (true) { var map = { diff --git a/packages/python/swig/prolog/yapi.yap b/packages/python/swig/prolog/yapi.yap index 5cd1303c1..63e69147a 100644 --- a/packages/python/swig/prolog/yapi.yap +++ b/packages/python/swig/prolog/yapi.yap @@ -74,7 +74,7 @@ python_query( Caller, String ) :- Caller.port := Status, write_query_answer( Bindings ), nl(user_error), - maplist(in_dict(Caller.answer, Bindings), Bindings). + maplist(in_dict(Caller.answer, Bindings), Bindings). /** * diff --git a/packages/python/yap_kernel/yap_ipython/yapi.py b/packages/python/yap_kernel/yap_ipython/yapi.py index a735623ef..6e964ee83 100644 --- a/packages/python/yap_kernel/yap_ipython/yapi.py +++ b/packages/python/yap_kernel/yap_ipython/yapi.py @@ -27,7 +27,7 @@ library = namedtuple('library', 'list') v = namedtuple('_', 'slot') load_files = namedtuple('load_files', 'file ofile args') python_query = namedtuple('python_query', 'query_mgr string') -jupyter_query = namedtuple('jupyter_query', 'self text query') +jupyter_call = namedtuple('jupyter_call', 'self program query') enter_cell = namedtuple('enter_cell', 'self' ) exit_cell = namedtuple('exit_cell', 'self' ) completions = namedtuple('completions', 'txt self' ) @@ -569,7 +569,7 @@ class YAPRun(InteractiveShell): self.answers = [] self.os = program+squery self.iterations = 0 - pg = jupyter_query( self, program, squery) + pg = jupyter_call( self, program, squery) self.query = self.yapeng.query(pg) self.answers = [] self.port = "call" @@ -580,7 +580,7 @@ class YAPRun(InteractiveShell): #sys.stderr.write('C '+ str(self.port) +'\n'+'\n') found = True print( "uek",self.answer ) - self.answers += [self.answer] + #self.answers += [self.answer] print( "ek",self.answers ) self.iterations += 1 if self.port == "exit" or stop or howmany == self.iterations: diff --git a/pl/top.yap b/pl/top.yap index f509bd134..aa90af689 100644 --- a/pl/top.yap +++ b/pl/top.yap @@ -558,7 +558,7 @@ write_query_answer( Bindings ) :- '$name_vars_in_goals1'([], I, I). '$name_vars_in_goals1'([V|NGVL], I0, IF) :- - I is I0+1, + I is I0+1, '$gen_name_string'(I0,[],SName), !, atom_codes(Name, [95|SName]), V = '$VAR'(Name), From 31423fcf909d3ed396c8d6c821397579d63f5a14 Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Fri, 21 Dec 2018 20:57:53 +0000 Subject: [PATCH 11/14] yapi --- C/parser.c | 10 +- os/readterm.c | 29 ++-- packages/python/pl2py.c | 10 +- packages/python/py2pl.c | 2 + packages/python/py4yap.h | 6 +- packages/python/pybips.c | 75 +++++----- packages/python/pyio.c | 130 ++++++++---------- packages/python/pypreds.c | 18 +++ packages/python/python.c | 3 +- packages/python/python.pl | 1 + packages/python/swig/CMakeLists.txt | 4 +- packages/python/swig/prolog/yapi.yap | 73 ++++++---- packages/python/swig/yap4py/yapi.py | 18 +-- .../yap_kernel/yap_ipython/prolog/jupyter.yap | 6 +- .../python/yap_kernel/yap_ipython/yapi.py | 91 +++++------- pl/control.yap | 22 +-- pl/top.yap | 8 +- pl/yapor.yap | 1 + 18 files changed, 260 insertions(+), 247 deletions(-) diff --git a/C/parser.c b/C/parser.c index b83ecb453..85a2ddb2b 100755 --- a/C/parser.c +++ b/C/parser.c @@ -58,14 +58,14 @@ extern const char *Yap_tokText(void *tokptr); static void syntax_msg(const char *msg, ...) { CACHE_REGS va_list ap; - if (!LOCAL_ErrorMessage || + if (!LOCAL_Error_TYPE || (LOCAL_Error_TYPE == SYNTAX_ERROR && - LOCAL_tokptr->TokPos < LOCAL_ActiveError->parserPos)) { + LOCAL_toktide->TokPos < LOCAL_ActiveError->parserPos)) { if (!LOCAL_ErrorMessage) { LOCAL_ErrorMessage = malloc(MAX_ERROR_MSG_SIZE + 1); } - LOCAL_ActiveError->parserLine = LOCAL_tokptr->TokLine; - LOCAL_ActiveError->parserPos = LOCAL_tokptr->TokPos; + LOCAL_ActiveError->parserLine = LOCAL_toktide->TokLine; + LOCAL_ActiveError->parserPos = LOCAL_toktide->TokPos; va_start(ap, msg); vsnprintf(LOCAL_ErrorMessage, MAX_ERROR_MSG_SIZE, msg, ap); va_end(ap); @@ -939,7 +939,7 @@ Term Yap_Parse(UInt prio, encoding_t enc, Term cmod) { Yap_CloseSlots(sls); } if (LOCAL_tokptr != NULL && LOCAL_tokptr->Tok != Ord(eot_tok)) { - LOCAL_Error_TYPE = SYNTAX_ERROR; + LOCAL_Error_TYPE =SYNTAX_ERROR; if (LOCAL_tokptr->TokNext) { size_t sz = strlen("bracket or operator expected."); LOCAL_ErrorMessage =malloc(sz+1); diff --git a/os/readterm.c b/os/readterm.c index 4a12db042..06bc2774a 100644 --- a/os/readterm.c +++ b/os/readterm.c @@ -402,15 +402,8 @@ static Term syntax_error(TokEntry *errtok, int sno, Term cmod, Int newpos, bool #endif if (GLOBAL_Stream[sno].status & Seekable_Stream_f) { - while (tok && tok->Tok != Error_tok && tok != errtok) - { - if (tok->TokNext) - tok = tok->TokNext; - else - break; - } - err_line = tok->TokLine; - errpos = tok->TokPos -1; + err_line = LOCAL_ActiveError->parserLine; + errpos = LOCAL_ActiveError->parserPos -1; if (errpos <= startpos) { o = malloc(1); @@ -457,7 +450,7 @@ static Term syntax_error(TokEntry *errtok, int sno, Term cmod, Int newpos, bool o[0] = '\0'; while (tok) { - if (tok->Tok == Error_tok) + if (tok->Tok == Error_tok || tok == LOCAL_toktide ) { o = realloc(o, strlen(o) + 1); Yap_local.ActiveError->parserTextA = o; @@ -488,15 +481,17 @@ static Term syntax_error(TokEntry *errtok, int sno, Term cmod, Int newpos, bool } } Yap_local.ActiveError->parserPos = errpos; - Yap_local.ActiveError->parserLine = err_line; - /* 0: strat, error, end line */ - /*2 msg */ - /* 1: file */ - if (!msg) - msg = "unspecified"; + Yap_local.ActiveError->parserLine = err_line; + /* 0: strat, error, end line */ + /*2 msg */ + /* 1: file */ Yap_local.ActiveError->culprit = + (char*)msg; + if (Yap_local.ActiveError->errorMsg) { Yap_local.ActiveError->errorMsg = (char*)msg; - Yap_local.ActiveError->errorMsgLen = strlen(msg); + Yap_local.ActiveError->errorMsgLen = strlen(Yap_local.ActiveError->errorMsg); + } + clean_vars(LOCAL_VarTable); clean_vars(LOCAL_AnonVarTable); if (Yap_ExecutionMode == YAP_BOOT_MODE) diff --git a/packages/python/pl2py.c b/packages/python/pl2py.c index 5cb964318..1ab854097 100644 --- a/packages/python/pl2py.c +++ b/packages/python/pl2py.c @@ -156,11 +156,10 @@ static bool entry_to_dictionary(PyObject *dict, Term targ, */ PyObject *term_to_python(term_t t, bool eval, PyObject *o, bool cvt) { // - YAP_Term yt = YAP_GetFromSlot(t); switch (PL_term_type(t)) { case PL_VARIABLE: { - if (yt == 0) { - Yap_ThrowError(SYSTEM_ERROR_INTERNAL, yt, "in term_to_python"); + if (t == 0) { + Yap_ThrowError(SYSTEM_ERROR_INTERNAL, t, "in term_to_python"); } PyObject *out = PyTuple_New(1); PyTuple_SET_ITEM(out, 0, PyLong_FromLong((YAP_Int)YAP_GetFromSlot(t))); @@ -169,6 +168,7 @@ PyObject *term_to_python(term_t t, bool eval, PyObject *o, bool cvt) { return term_to_nametuple("v", 1, out); }; case PL_ATOM: { + YAP_Term yt = YAP_GetFromSlot(t); YAP_Atom at = YAP_AtomOfTerm(yt); const char *s; @@ -189,6 +189,7 @@ PyObject *term_to_python(term_t t, bool eval, PyObject *o, bool cvt) { } } case PL_STRING: { + YAP_Term yt = YAP_GetFromSlot(t); const char *s = NULL; if (YAP_IsAtomTerm(yt)) { s = YAP_AtomName(YAP_AtomOfTerm(yt)); @@ -389,6 +390,9 @@ PyObject *term_to_python(term_t t, bool eval, PyObject *o, bool cvt) { else return Py_None; } + if (fun == FUNCTOR_var1) { + return Py_None; + } atom_t name; int arity; diff --git a/packages/python/py2pl.c b/packages/python/py2pl.c index 9b88d91cc..b8160d88c 100644 --- a/packages/python/py2pl.c +++ b/packages/python/py2pl.c @@ -155,6 +155,8 @@ else if (PyDict_Check(pVal)) { Py_ssize_t pos = 0, tot = PyDict_Size(pVal); PyObject *key, *value; Term f, *opt = &f, t, to; + if (tot == 0) + return MkAtomTerm( Yap_LookupAtom("{}")); while (PyDict_Next(pVal, &pos, &key, &value)) { Term t0[2]; t0[0] = python_to_term__(key); diff --git a/packages/python/py4yap.h b/packages/python/py4yap.h index 79c29543a..bae0be539 100644 --- a/packages/python/py4yap.h +++ b/packages/python/py4yap.h @@ -70,16 +70,16 @@ extern bool init_python_vfs(void); 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_nil, - ATOM_brackets, ATOM_curly_brackets; + ATOM_brackets, ATOM_curly_brackets; extern functor_t FUNCTOR_dollar1, FUNCTOR_abs1, FUNCTOR_all1, FUNCTOR_any1, FUNCTOR_as2, FUNCTOR_bin1, FUNCTOR_brackets1, FUNCTOR_comma2, FUNCTOR_dir1, - FUNCTOR_float1, FUNCTOR_int1, FUNCTOR_iter1, FUNCTOR_iter2, FUNCTOR_long1, + FUNCTOR_float1, FUNCTOR_int1, FUNCTOR_iter1, FUNCTOR_var1, FUNCTOR_iter2, FUNCTOR_long1, FUNCTOR_var1, 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_dot2, FUNCTOR_var1; extern X_API PyObject *py_Main; extern X_API PyObject *py_Yapex; diff --git a/packages/python/pybips.c b/packages/python/pybips.c index ded76ada8..986162d01 100644 --- a/packages/python/pybips.c +++ b/packages/python/pybips.c @@ -591,7 +591,6 @@ 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}, @@ -601,17 +600,16 @@ static long get_len_of_range(long lo, long hi, long step) { {"A24", NULL}, {"A25", NULL}, {"A26", NULL}, {"A27", NULL}, {"A28", NULL}, {"A29", NULL}, {"A29", NULL}, {"A30", NULL}, {"A31", NULL}, {"A32", NULL}, {NULL, NULL}}; -*/ -static PyObject *structseq_str(PyObject *iobj) { + static PyObject *structseq_str(PyStructSequence *obj ) { /* 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; + PyTypeObject *typ = Py_TYPE(obj); + const char *type_name = typ->tp_name; Py_ssize_t len, i; char buf[REPR_BUFFER_SIZE]; char *endofbuf, *pbuf = buf; @@ -620,8 +618,8 @@ static PyObject *structseq_str(PyObject *iobj) { /* "typename(", limited to TYPE_MAXSIZE */ len = - strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE : strlen(typ->tp_name); - strncpy(pbuf, typ->tp_name, len); + strnlen(type_name, TYPE_MAXSIZE); + strncpy(pbuf, type_name, len); pbuf += len; *pbuf++ = '('; @@ -666,7 +664,7 @@ static PyObject *structseq_str(PyObject *iobj) { return PyUnicode_FromString(buf); } -static PyObject *structseq_repr(PyObject *iobj) { + static PyObject *structseq_repr(PyObject *iobj) { /* buffer and type size were chosen well considered. */ #define REPR_BUFFER_SIZE 512 @@ -674,6 +672,7 @@ static PyObject *structseq_repr(PyObject *iobj) { PyStructSequence *obj = (PyStructSequence *)iobj; PyTypeObject *typ = Py_TYPE(obj); + const char *type_name = typ->tp_name; bool removelast = false; Py_ssize_t len, i; char buf[REPR_BUFFER_SIZE]; @@ -683,8 +682,8 @@ static PyObject *structseq_repr(PyObject *iobj) { /* "typename(", limited to TYPE_MAXSIZE */ len = - strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE : strlen(typ->tp_name); - strncpy(pbuf, typ->tp_name, len); + strnlen(type_name, TYPE_MAXSIZE); + strncpy(pbuf, type_name, len); pbuf += len; *pbuf++ = '('; @@ -743,7 +742,7 @@ static bool legal_symbol(const char *s) { PyObject *term_to_nametuple(const char *s, arity_t arity, PyObject *tuple) { PyTypeObject *typp; PyObject *key = PyUnicode_FromString(s), *d; - if (!legal_symbol(s)) { + if (legal_symbol(s)) { if (!Py_f2p) { PyObject *o1; @@ -761,32 +760,42 @@ PyObject *term_to_nametuple(const char *s, arity_t arity, PyObject *tuple) { if ((d = PyList_GetItem(Py_f2p, arity - 1)) && PyDict_Contains(d, key)) { typp = (PyTypeObject *)d; } else { - typp = calloc(sizeof(PyTypeObject), 1); - PyStructSequence_Desc *desc = calloc(sizeof(PyStructSequence_Desc), 1); + PyStructSequence_Desc *desc = PyMem_Calloc(sizeof(PyStructSequence_Desc), 1); desc->name = PyMem_Malloc(strlen(s) + 1); + strcpy(desc->name, s); desc->doc = "YAPTerm"; - desc->fields = NULL; + desc->fields = pnull; desc->n_in_sequence = arity; + typp = PyStructSequence_NewType(desc); + typp->tp_name = desc->name; + if (PyStructSequence_InitType2(typp, desc) < 0) return NULL; - // typp->tp_flags &= ~Py_TPFLAGS_HEAPTYPE; - // typp->tp_flags &= ~Py_TPFLAGS_HAVE_GC; - // typp->tp_str = structseq_str; - typp->tp_repr = structseq_repr; - // typp = PyStructSequence_NewType(desc); + typp->tp_traverse = NULL; + typp->tp_flags |= + Py_TPFLAGS_TUPLE_SUBCLASS| + Py_TPFLAGS_BASETYPE| + Py_TPFLAGS_HEAPTYPE; // don't do this: we cannot add a type as an atribute. // PyModule_AddGObject(py_Main, s, (PyObject *)typp); - if (d && !PyDict_Contains(d, key)) - PyDict_SetItem(d, key, (PyObject*)typp); + if (d && !PyDict_Contains(d, key)) { + PyDict_SetItem(d, key, (void*)typp); + Py_INCREF(key); + Py_INCREF(typp); + } + typp->tp_repr = structseq_repr; + typp->tp_str = structseq_str; } PyObject *o = PyStructSequence_New(typp); Py_INCREF(typp); arity_t i; for (i = 0; i < arity; i++) { PyObject *pArg = PyTuple_GET_ITEM(tuple, i); + if (pArg) { Py_INCREF(pArg); - if (pArg) PyStructSequence_SET_ITEM(o, i, pArg); + + } // PyObject_Print(pArg,stderr,0);fputc('\n',stderr); } //((PyStructSequence *)o)->ob_base.ob_size = arity; @@ -860,6 +869,9 @@ PyObject *compound_to_pytree(term_t t, PyObject *context, bool cvt) { atom_t name; int arity; + if (PL_is_variable(t)) { + return term_to_python(t, false, context, cvt); + } o = find_obj(context, t, false); AOK(PL_get_name_arity(t, &name, &arity), NULL); if (arity == 0) @@ -876,27 +888,26 @@ PyObject *compound_to_pytree(term_t t, PyObject *context, bool cvt) { if (!(s = PL_atom_chars(name))) { return NULL; } - term_t tleft; + Term tleft; int i; PyObject *out = PyTuple_New(arity); - DebugPrintf("Tuple %p\n", o); - tleft = PL_new_term_ref(); + if (CHECKNULL(t, out) == NULL) { + PyErr_Print(); + return NULL; + } + //DebugPrintf("Tuple %s/%d = %p\n", name, arity, out); for (i = 0; i < arity; i++) { PyObject *pArg; - AOK(PL_get_arg(i + 1, t, tleft), NULL); - pArg = term_to_python(tleft, false, NULL, cvt); + tleft = ArgOfTerm(i + 1, Yap_GetFromSlot(t)); + pArg = yap_to_python(tleft, false, NULL, cvt); if (pArg) { /* pArg reference stolen here: */ PyTuple_SET_ITEM(out, i, pArg); Py_INCREF(pArg); } } - if (CHECKNULL(t, out) == NULL) { - PyErr_Print(); - return NULL; - } - PyObject *c = lookupPySymbol(s, o, NULL); + PyObject *c = lookupPySymbol(s, out, NULL); if (c && PyCallable_Check(c)) { PyObject *n = PyTuple_New(arity); diff --git a/packages/python/pyio.c b/packages/python/pyio.c index 8e16fa55d..e0a7813ce 100644 --- a/packages/python/pyio.c +++ b/packages/python/pyio.c @@ -8,9 +8,15 @@ YAP_Term TermErrStream, TermOutStream; -static void pyflush(StreamDesc *st) { +static void py_flush(int sno) { + StreamDesc *st = YAP_GetStreamFromId(sno); + PyObject *fl = + PyObject_GetAttrString(st->u.private_data, "flush"); + if (fl) { + PyObject_CallFunctionObjArgs(fl, + NULL); + } #if 0 - st->u.w_irl.ptr[0] = '\0'; // fprintf(stderr,"%s\n", st->u.w_irl.buf); term_t tg = python_acquire_GIL(); if (st->user_name == TermOutStream){ @@ -31,13 +37,13 @@ static int py_putc(int sno, int ch) { StreamDesc *st = YAP_GetStreamFromId(sno); #if 0 if (false && (st->user_name == TermOutStream || st->user_name == TermErrStream)) { - size_t sz = put_utf8(st->u.w_irl.ptr, ch); - if (sz > 0) { - st->u.w_irl.ptr += sz; - if (ch == '\n' || st->u.w_irl.ptr - st->u.w_irl.buf > 256) - {pyflush(st); } - } - return ch; + size_t sz = put_utf8(st->u.w_irl.ptr, ch); + if (sz > 0) { + st->u.w_irl.ptr += sz; + if ( st->u.w_irl.ptr - st->u.w_irl.buf > 256) + {py_flush(sno); } + } + return ch; } #endif unsigned char s[2]; @@ -50,8 +56,8 @@ static int py_putc(int sno, int ch) { python_release_GIL(g0); if ((err = PyErr_Occurred())) { PyErr_SetString( - err, - "Error in put\n"); // %s:%s:%d!\n", __FILE__, __FUNCTION__, __LINE__); + err, + "Error in put\n"); // %s:%s:%d!\n", __FILE__, __FUNCTION__, __LINE__); } return ch; } @@ -63,13 +69,13 @@ static int py_wputc(int sno, int ch) { StreamDesc *st = YAP_GetStreamFromId(sno); #if 0 if (false && (st->user_name == TermOutStream || st->user_name == TermErrStream)) { - size_t sz = put_utf8(st->u.w_irl.ptr, ch); - if (sz > 0) { - st->u.w_irl.ptr += sz; - if (ch == '\n' || st->u.w_irl.ptr - st->u.w_irl.buf > 256) - {pyflush(st); } - } - return ch; + size_t sz = put_utf8(st->u.w_irl.ptr, ch); + if (sz > 0) { + st->u.w_irl.ptr += sz; + if ( st->u.w_irl.ptr - st->u.w_irl.buf > 256) + {py_flush(sno); } + } + return ch; } #endif unsigned char s[8]; @@ -82,8 +88,8 @@ static int py_wputc(int sno, int ch) { python_release_GIL(g0); if ((err = PyErr_Occurred())) { PyErr_SetString( - err, - "Error in put\n"); // %s:%s:%d!\n", __FILE__, __FUNCTION__, __LINE__); + err, + "Error in put\n"); // %s:%s:%d!\n", __FILE__, __FUNCTION__, __LINE__); } return ch; } @@ -112,16 +118,16 @@ static void *py_open(VFS_t *me, const char *name, const char *io_mode, } /* if (!outbuf) - outbuf = ( unsigned char *)malloc(1024); + outbuf = ( unsigned char *)malloc(1024); st->u.w_irl.ptr = st->u.w_irl.buf = outbuf; -]\] + ]\] st->user_name = TermOutStream; - } else if (strcmp(name, "sys.stderr") == 0) { + } else if (strcmp(name, "sys.stderr") == 0) { st->user_name = TermErrStream; if (!errbuf) - errbuf = ( unsigned char *)malloc(1024); + errbuf = ( unsigned char *)malloc(1024); st->u.w_irl.ptr = st->u.w_irl.buf = errbuf; // } else if (strcmp(name, "input") == 0) { //pystream = PyObject_Call(pystream, PyTuple_New(0), NULL); @@ -131,18 +137,11 @@ static void *py_open(VFS_t *me, const char *name, const char *io_mode, st->vfs = me; st->file = NULL; python_release_GIL(ctk); + if (st->status & (Output_Stream_f | Append_Stream_f)) + py_flush(sno); return st; } -static void py_flush(int sno) { - StreamDesc *s = YAP_GetStreamFromId(sno); - term_t tg = python_acquire_GIL(); - PyObject *flush = PyObject_GetAttrString(s->u.private_data, "flush"); - pyflush(s); - PyObject_CallFunction(flush, NULL); - python_release_GIL(tg); -} - static bool py_close(int sno) { StreamDesc *st = YAP_RepStreamFromId(sno); if (st->status & (Output_Stream_f | Append_Stream_f)) @@ -158,49 +157,36 @@ static bool py_close(int sno) { } static bool pygetLine(StreamDesc *rl_iostream, int sno) { - // term_t ctk = python_acquire_GIL(); const char *myrl_line; - PyObject *user_line, *readl = NULL; + PyObject *user_line; PyObject *err; StreamDesc *s = YAP_GetStreamFromId(sno); - // term_t tg = python_acquire_GIL(); - PyObject_Print(s->u.private_data,stderr,0); + term_t tg = python_acquire_GIL(); + // PyObject_Print(s->u.private_data,stderr,0); if (PyFunction_Check( s->u.private_data )) { - readl = s->u.private_data; + user_line = PyObject_CallFunctionObjArgs( s->u.private_data , + NULL); + } else if ( s->u.private_data == NULL) { + PyObject *readl = + PyObject_GetAttrString(s->u.private_data, "readline"); + if (!readl) { + readl = + PyObject_GetAttrString(s->u.private_data, "read"); } - if (!strcmp(RepAtom(s->name)->StrOfAE, "user_input")) { - // note that input may change - readl = PythonLookupSpecial("input"); + if (readl) + user_line = PyObject_CallFunctionObjArgs(readl, + NULL); } - if (readl == NULL) { - readl = PythonLookup("readline", s->u.private_data); + python_release_GIL(tg); + if ((err = PyErr_Occurred())) { + if (PyErr_GivenExceptionMatches(err, PyExc_EOFError)) + return NULL; + PyErr_Print(); + Yap_ThrowError(SYSTEM_ERROR_GET_FAILED, YAP_MkIntTerm(sno), NULL); } - if (readl == NULL) { - readl = PythonLookup("read", s->u.private_data); - } - if (readl == NULL) { - if ((err = PyErr_Occurred())) { - PyErr_Print(); - Yap_ThrowError(SYSTEM_ERROR_GET_FAILED, YAP_MkIntTerm(sno), NULL); - } - } - user_line = PyObject_CallFunctionObjArgs(readl, - NULL); - if ((err = PyErr_Occurred())) { - PyErr_Print(); - Yap_ThrowError(SYSTEM_ERROR_GET_FAILED, YAP_MkIntTerm(sno), err); - } myrl_line = PyUnicode_AsUTF8(user_line); if (myrl_line == NULL) return NULL; - if ((err = PyErr_Occurred())) { - - if (PyErr_GivenExceptionMatches(err, PyExc_EOFError)) - return NULL; - PyErr_Print(); - Yap_ThrowError(SYSTEM_ERROR_GET_FAILED, YAP_MkIntTerm(sno), err); - - } rl_iostream->u.irl.ptr = rl_iostream->u.irl.buf = (unsigned char *)myrl_line; return true; } @@ -247,11 +233,11 @@ static int py_wgetc(int sno) { } /** - @brief Yap_ReadlinePeekChar peeks the next char from the - readline buffer, but does not actually grab it. + @brief Yap_ReadlinePeekChar peeks the next char from the + readline buffer, but does not actually grab it. - The idea is to take advantage of the buffering. Special care must be taken - with EOF, though. + The idea is to take advantage of the buffering. Special care must be taken + with EOF, though. */ static int py_peek(int sno) { @@ -280,7 +266,7 @@ static int py_peek(int sno) { static int64_t py_seek(int sno, int64_t where, int how) { StreamDesc *g0 = YAP_RepStreamFromId(sno); term_t s0 = python_acquire_GIL(); - PyObject *fseek = PyObject_GetAttrString(g0->u.private_data, "seek"); + PyObject *fseek = PyObject_GetAttrString(g0->u.private_data, "seek"); PyObject *pyr = PyObject_CallFunctionObjArgs(fseek, PyLong_FromLong(where), PyLong_FromLong(how), NULL); python_release_GIL(s0); @@ -311,7 +297,7 @@ bool init_python_vfs(void) { initialized = true; pystream.name = "python stream"; pystream.vflags = - VFS_CAN_WRITE | VFS_CAN_EXEC | VFS_CAN_READ | VFS_HAS_PREFIX; + VFS_CAN_WRITE | VFS_CAN_EXEC | VFS_CAN_READ | VFS_HAS_PREFIX; pystream.prefix = "/python/"; pystream.suffix = NULL; pystream.open = py_open; diff --git a/packages/python/pypreds.c b/packages/python/pypreds.c index 9dc6d4cbf..20cf338c8 100644 --- a/packages/python/pypreds.c +++ b/packages/python/pypreds.c @@ -26,6 +26,23 @@ static foreign_t python_len(term_t tobj, term_t tf) { len = PyObject_Length(o); pyErrorAndReturn(PL_unify_int64(tf, len)); } + +static foreign_t python_represent( term_t name, term_t tobj) { + term_t stackp = python_acquire_GIL(); + PyObject *e; + + e = term_to_python(tobj, false, NULL, true); + if (e == NULL) { + python_release_GIL(stackp); + pyErrorAndReturn(false); + } + bool b = python_assign(name, e, NULL); + python_release_GIL(stackp); + pyErrorAndReturn(b); +} + + + static foreign_t python_clear_errors(void) { PyErr_Clear(); return true; @@ -744,6 +761,7 @@ install_t install_pypreds(void) { PL_register_foreign("python_index", 3, python_index, 0); PL_register_foreign("python_field", 3, python_field, 0); PL_register_foreign("python_assign", 2, assign_python, 0); + PL_register_foreign("python_represents", 2, python_represent, 0); PL_register_foreign("python_export", 2, python_export, 0); PL_register_foreign("python_function", 1, python_function, 0); PL_register_foreign("python_slice", 4, python_slice, 0); diff --git a/packages/python/python.c b/packages/python/python.c index 7738d277b..e8b35ae9b 100644 --- a/packages/python/python.c +++ b/packages/python/python.c @@ -30,7 +30,7 @@ functor_t FUNCTOR_dollar1, FUNCTOR_abs1, FUNCTOR_all1, FUNCTOR_any1, FUNCTOR_as2 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; + FUNCTOR_dot2, FUNCTOR_brackets1, FUNCTOR_var1; X_API PyObject *py_Atoms; X_API PyObject *py_Yapex; @@ -110,6 +110,7 @@ static void install_py_constants(void) { FUNCTOR_comma2 = PL_new_functor(PL_new_atom(","), 2); FUNCTOR_equal2 = PL_new_functor(PL_new_atom("="), 2); FUNCTOR_sqbrackets2 = PL_new_functor(PL_new_atom("[]"), 2); + FUNCTOR_var1 = PL_new_functor(PL_new_atom("$VAR"), 1); } foreign_t end_python(void) { diff --git a/packages/python/python.pl b/packages/python/python.pl index 7cf3cc275..85c94ef69 100644 --- a/packages/python/python.pl +++ b/packages/python/python.pl @@ -23,6 +23,7 @@ python_run_command/1, python_run_script/2, python_assign/3, + python_represents/2, python_import/1, array_to_python_list/4, array_to_python_tuple/4, diff --git a/packages/python/swig/CMakeLists.txt b/packages/python/swig/CMakeLists.txt index 6c607c007..551b6fea0 100644 --- a/packages/python/swig/CMakeLists.txt +++ b/packages/python/swig/CMakeLists.txt @@ -6,7 +6,9 @@ INCLUDE(UseSWIG) include(FindPythonModule) list (APPEND pl_library ${CMAKE_CURRENT_SOURCE_DIR}/prolog/yapi.yap ) -set (PYTHON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/yap4py/yapi.py ${CMAKE_CURRENT_SOURCE_DIR}/yap4py/__main__.py) +set (PYTHON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/yap4py/yapi.py + ${CMAKE_CURRENT_SOURCE_DIR}/yap4py/systuples.py + ${CMAKE_CURRENT_SOURCE_DIR}/yap4py/__main__.py) SET_SOURCE_FILES_PROPERTIES(../../swig/yap.i PROPERTIES CPLUSPLUS ON) diff --git a/packages/python/swig/prolog/yapi.yap b/packages/python/swig/prolog/yapi.yap index a540f0ad6..dbf909df0 100644 --- a/packages/python/swig/prolog/yapi.yap +++ b/packages/python/swig/prolog/yapi.yap @@ -25,18 +25,19 @@ :- python_import(yap4py.yapi). +:- python_import(json). %:- python_import(gc). :- meta_predicate( yapi_query(:,+) ). %:- start_low_level_trace. - %% @pred yapi_query( + VarList, - Dictionary) - %% - %% dictionary, Examples - %% - %% - yapi_query( VarNames, Self ) :- +%% @pred yapi_query( + VarList, - Dictionary) +%% +%% dictionary, Examples +%% +%% +yapi_query( VarNames, Self ) :- show_answer(VarNames, Dict), Self.bindings := Dict. @@ -47,6 +48,9 @@ set_preds :- fail, current_predicate(P, Q), functor(Q,P,A), + + current_predicate(P, Q), + functor(Q,P,A), atom_string(P,S), catch( := yap4py.yapi.named( S, A), @@ -72,27 +76,46 @@ python_query( Caller, String ) :- atomic_to_term( String, Goal, VarNames ), query_to_answer( Goal, VarNames, Status, Bindings), Caller.port := Status, - write_query_answer( Bindings ), - nl(user_error), - maplist(in_dict(Caller.answer, Bindings), Bindings). ->>>>>>> 37d5dcedc17b8c63cd9fa213454edb37816a130f + write_query_answer( Bindings ), + answer := {}, + foldl(ground_dict(answer), Bindings, [], Ts), + term_variables( Ts, Hidden), + foldl(bv, Hidden , 0, _), + maplist(into_dict(answer),Ts), + Caller.answer := json.dumps(answer), + S := Caller.answer, +format(user_error, '~nor ~s~n~n',S). + +bv(V,I,I1) :- + atomic_concat(['__',I],V), + I1 is I+1. + +into_dict(D,V0=T) :- + D[V0] := T. + /** * */ -in_dict(_Dict, _, var([_V0])) :- - !. -in_dict(Dict, Bindings, var([V0,V|Vs])) :- - !, - atom_to_string(V0,S0), - atom_to_string(V,S), - Dict[S] := S0, - in_dict( Dict, Bindings, var([V0|Vs])). -in_dict(Dict, Bindings, nonvar([V0|Vs], T)) :- - !, - atom_to_string(V0,S0), - term_to_string(T, S, _Bindings), - Dict[S0] := S, - in_dict( Dict, Bindings, var([V0|Vs])). -in_dict(_, _, _). +ground_dict(_Dict, var([V,V]), I, I) :- + !. +ground_dict(Dict, nonvar([V0|Vs], T),I0, [V0=T| I0]) :- + !, + ground_dict( Dict, var([V0|Vs]), I0, I0). +ground_dict(Dict, var([V0,V|Vs]), I, I) :- + !, + Dict[V]=V0, + ground_dict( Dict, var([V0|Vs]), I, I). +ground_dict(_, _, _, _). + + +bound_dict(Dict, nonvar([V0|Vs], T)) :- + !, + Dict[V0] := T, + bound_dict( Dict, var([V0|Vs])). +bound_dict(Dict, var([V0,V|Vs])) :- + !, + Dict[V] := V0, + bound_dict( Dict, var([V0|Vs])). +bound_dict(_, _). diff --git a/packages/python/swig/yap4py/yapi.py b/packages/python/swig/yap4py/yapi.py index 3763ad04b..c25157075 100644 --- a/packages/python/swig/yap4py/yapi.py +++ b/packages/python/swig/yap4py/yapi.py @@ -1,22 +1,12 @@ import readline from yap4py.yap import * +from yap4py.systuples import * from os.path import join, dirname -from collections import namedtuple + import sys yap_lib_path = dirname(__file__) -bindvars = namedtuple('bindvars', 'list') -compile = namedtuple('compile', 'file') -jupyter_query = namedtuple('jupyter_query', 'vars dict') -library = namedtuple('library', 'listfiles') -prolog_library = namedtuple('prolog_library', 'listfiles') -python_query = namedtuple('python_query', 'vars dict') -set_prolog_flag = namedtuple('set_prolog_flag', 'flag new_value') -show_answer = namedtuple('show_answer', 'vars dict') -v0 = namedtuple('v', 'slot') -yap_query = namedtuple('yap_query', 'query owner') -yapi_query = namedtuple('yapi_query', 'vars dict') class Engine( YAPEngine ): @@ -140,7 +130,7 @@ class YAPShell: # construct a query from a one-line string # q is opaque to Python # - #q = engine.query(python_query(self, s)) + # q = engine.query(python_query(self, s)) # # # vs is the list of variables # you can print it out, the left-side is the variable name, @@ -160,7 +150,7 @@ class YAPShell: q = Query( engine, python_query( engine, query) ) for answer in q: bindings += [answer] - if g.done(): + if q.done(): return bindings if loop: continue diff --git a/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap b/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap index 09f21f89b..4e1eab760 100644 --- a/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap +++ b/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap @@ -8,7 +8,7 @@ :- yap_flag(gc_trace,verbose). /* :- module( jupyter, - [jupyter_query/3, + [jupyter_queryl/3, blank/1, streams/2 ] @@ -27,6 +27,8 @@ :- python_import(sys). + + jupyter_query(Caller, Cell, Line ) :- jupyter_cell(Caller, Cell, Line). @@ -42,7 +44,7 @@ jupyter_cell(Caller, _, Line ) :- catch( python_query(Query,Line), error(A,B), - (writeln(A,B),system_error(A,B)) + system_error(A,B) ). restreams(call) :- diff --git a/packages/python/yap_kernel/yap_ipython/yapi.py b/packages/python/yap_kernel/yap_ipython/yapi.py index ad47d4818..bfd9af7e9 100644 --- a/packages/python/yap_kernel/yap_ipython/yapi.py +++ b/packages/python/yap_kernel/yap_ipython/yapi.py @@ -5,6 +5,7 @@ from typing import List from traitlets import Bool +from yap4py.systuples import * from yap4py.yapi import * from IPython.core.completer import Completer # import IPython.core @@ -18,23 +19,8 @@ from ipython_genutils.py3compat import builtin_mod from yap_kernel.displayhook import ZMQShellDisplayHook -from collections import namedtuple import traceback -use_module = namedtuple('use_module', 'file') -bindvars = namedtuple('bindvars', 'list') -library = namedtuple('library', 'list') -v = namedtuple('_', 'slot') -load_files = namedtuple('load_files', 'file ofile args') -python_query = namedtuple('python_query', 'query_mgr string') -jupyter_call = namedtuple('jupyter_call', 'self program query') -enter_cell = namedtuple('enter_cell', 'self' ) -exit_cell = namedtuple('exit_cell', 'self' ) -completions = namedtuple('completions', 'txt self' ) -errors = namedtuple('errors', 'self text' ) -streams = namedtuple('streams', 'text' ) -nostreams = namedtuple('nostreams', ' text' ) - global engine def tracefunc(frame, event, arg, indent=[0]): @@ -70,7 +56,7 @@ class YAPInputSplitter(InputSplitter): logical_line_transforms=None): self._buffer_raw = [] self._validate = True - self.yapeng = engine + self.engine = engine self.shell = shell if physical_line_transforms is not None: @@ -392,7 +378,7 @@ class YAPCompleter(Completer): return ( magic.startswith(bare_text) and magic not in global_matches ) else: - def matches(magic): + def matches(magic): return magic.startswith(bare_text) comp = [ pre2+m for m in cell_magics if matches(m)] @@ -503,7 +489,7 @@ class YAPCompleter(Completer): magic_res = self.magic_matches(text) return text, magic_res self.matches = [] - prolog_res = self.shell.yapeng.mgoal(completions(text, self), "user",True) + prolog_res = self.shell.engine.mgoal(completions(text, self), "user",True) return text, self.matches @@ -515,9 +501,9 @@ class YAPRun(InteractiveShell): def __init__(self, shell): self.shell = shell - self.yapeng = JupyterEngine() + self.engine = JupyterEngine() global engine - engine = self.yapeng + engine = self.engine self.errors = [] self.query = None self.os = None @@ -525,8 +511,9 @@ class YAPRun(InteractiveShell): self.port = "None" self.answers = None self.bindings = dicts = [] - self.shell.yapeng = self.yapeng + self.shell.engine = self.engine self._get_exc_info = shell._get_exc_info + self.iterations = 0 def showtraceback(self, exc_info): @@ -547,57 +534,46 @@ class YAPRun(InteractiveShell): return self.errors self.errors=[] (text,_,_,_) = self.clean_end(text) - self.yapeng.mgoal(errors(self,text),"user",True) + self.engine.mgoal(errors(self,text),"user",True) return self.errors - def prolog(self, s): + def prolog(self, s, result): # # construct a self.queryuery from a one-line string # self.query is opaque to Python try: - program,squery,stop,howmany = self.prolog_cell(s) - found = False + program,squery,_ ,howmany = self.prolog_cell(s) # sys.settrace(tracefunc) - if self.query and self.os == program+squery: + if self.query and self.os == (program,squery): howmany += self.iterations - found = howmany != 0 else: if self.query: self.query.close() self.query = None - self.port = None self.answers = [] - self.os = program+squery + self.os = (program,squery) self.iterations = 0 - pg = jupyter_call( self, program, squery) - self.query = self.yapeng.query(pg) + pg = jupyter_query(self.engine,program,squery) + self.query = Query(self.engine, pg) self.answers = [] - self.port = "call" - found = False - self.answer = {} - while self.query.next(): - #sys.stderr.write('B '+str( self.answer) +'\n') - #sys.stderr.write('C '+ str(self.port) +'\n'+'\n') - found = True - print( "uek",self.answer ) - #self.answers += [self.answer] - print( "ek",self.answers ) + for answer in self.query: + self.answers += [answer] self.iterations += 1 - if self.port == "exit" or stop or howmany == self.iterations: - self.os = None - self.query.close() - self.query = None - if found: - sys.stderr.write('Completed, with '+str(self.answers)+'\n') - result.result = self.answers - return result.results + + self.os = None + self.query.close() + self.query = None + if self.answers: + sys.stderr.write('Completed, with '+str(self.answers)+'\n') + result.result = self.answers + return result.result except Exception as e: sys.stderr.write('Exception '+str(e)+'in query '+ str(self.query)+ - ':'+pg+'\n '+str( self.bindings)+ '\n') + '\n '+str( self.bindings)+ '\n') has_raised = True result.result = [] - return result + return result.result @@ -720,7 +696,7 @@ class YAPRun(InteractiveShell): try: builtin_mod.input = input self.shell.input = input - self.yapeng.mgoal(streams(True),"user", True) + self.engine.mgoal(streams(True),"user", True) if cell.strip('\n \t'): #create a Trace object, telling it what to ignore, and whether to # do tracing or line-counting or both. @@ -736,10 +712,11 @@ class YAPRun(InteractiveShell): # run the new command using the given tracer # # tracer.runfunc(f,self,cell,state) - self.prolog( cell ) - # state = tracer.runfunc(jupyter_query( self, cell ) ) - self.shell.last_execution_succeeded = True - result.result = [] + answers = self.prolog( cell, result ) + # state = tracer.runfunc(hist + # er_query( self, cell ) ) + self.shell.last_execution_succeeded = True + result.result = answers except Exception as e: has_raised = True result.result = [] @@ -766,7 +743,7 @@ class YAPRun(InteractiveShell): # Each cell is a *single* input, regardless of how many lines it has self.shell.execution_count += 1 - self.yapeng.mgoal(streams(False),"user", True) + self.engine.mgoal(streams(False),"user", True) return def clean_end(self,s): diff --git a/pl/control.yap b/pl/control.yap index b6307a5d8..c00c55652 100644 --- a/pl/control.yap +++ b/pl/control.yap @@ -389,20 +389,20 @@ version(T) :- fail. '$set_toplevel_hook'(_). -query_to_answer(G, V, Status, Bindings) :- - gated_call( true, (G,'$delayed_goals'(G, V, Vs, LGs, _DCP)), Status, '$answer'( Status, LGs, Vs, Bindings) ). +query_to_answer(G, V, Status, Vs) :- + gated_call( true, (G,'$delayed_goals'(G, V, Vs, LGs, _DCP)), Status, '$answer'( Status, LGs, Vs ) ). - '$answer'( exit, LGs, Vs, Bindings) :- - !, - '$process_answer'(Vs, LGs, Bindings). - '$answer'( answer, LGs, Vs, Bindings) :- - !, - '$process_answer'(Vs, LGs, Bindings). -'$answer'(!, _, _, _). -'$answer'(fail,_,_,_). +'$answer'( exit, LGs, Vs) :- + !. %, +%'$process_answer'(Vs, LGs). +'$answer'( answer, LGs, Vs) :- + !. %, +% '$process_answer'(Vs, LGs, Bindings). +'$answer'(!, _, _). +'$answer'(fail,_,_). '$answer'(exception(E),_,_,_) :- '$LoopError'(E,error). -'$answer'(external_exception(_),_,_,_). +'$answer'(external_exception(_),_,_). %% @} diff --git a/pl/top.yap b/pl/top.yap index 00d5bf2ca..b48018a63 100644 --- a/pl/top.yap +++ b/pl/top.yap @@ -330,10 +330,10 @@ live :- '$process_answer'(Vs, LGs, Bindings) :- -'$purge_dontcares'(Vs,IVs), -'$sort'(IVs, NVs), -'$prep_answer_var_by_var'(NVs, LAnsw, LGs), -'$name_vars_in_goals'(LAnsw, Vs, Bindings). + '$purge_dontcares'(Vs,IVs), + '$sort'(IVs, NVs), + '$prep_answer_var_by_var'(NVs, LAnsw, LGs), + '$name_vars_in_goals'(LAnsw, Vs, Bindings). % % *-> at this point would require compiler support, which does not exist. diff --git a/pl/yapor.yap b/pl/yapor.yap index ee58b3e7c..2684a2f94 100644 --- a/pl/yapor.yap +++ b/pl/yapor.yap @@ -1,3 +1,4 @@ + /** * @file yapor.yap * @author VITOR SANTOS COSTA From 664c17f3b39f7dd48fb46a24a2e059cd9e67bdc4 Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Fri, 21 Dec 2018 22:51:52 +0000 Subject: [PATCH 12/14] tuples --- packages/python/swig/yap4py/systuples.py | 41 ++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 packages/python/swig/yap4py/systuples.py diff --git a/packages/python/swig/yap4py/systuples.py b/packages/python/swig/yap4py/systuples.py new file mode 100644 index 000000000..4db75a74b --- /dev/null +++ b/packages/python/swig/yap4py/systuples.py @@ -0,0 +1,41 @@ +from collections import namedtuple + +asserta = namedtuple('asserta', 'clause') +assertz = namedtuple('assertz', 'clause') +bindvars = namedtuple('bindvars', 'list') +compile = namedtuple('compile', 'file') +compdletionsile = namedtuple('completions', 'text self') +dbms = namedtuple('dbms', 'filedbms') +errors = namedtuple('errors', 'fileng engee') +foreign = namedtuple('foreign', 'filedbms') +jupyter_query = namedtuple('jupyter_query', 'engine program query') +library = namedtuple('library', 'listfiles') +load_files = namedtuple('load_file', 'file opts') +ostreams = namedtuple('ostreams', ' text') +prolog_library=namedtuple('prolog_library', 'listfiles') +python_query = namedtuple('python_query', 'engine query') +set_prolog_flag = namedtuple('set_prolog_flag', 'flag new_value') +show_answer = namedtuple('show_answer', 'vars dict') +streams = namedtuple('streams', 'text') +v = namedtuple('_', 'slot') +v0 = namedtuple('v', 'slot') +yap_query = namedtuple('yap_query', 'query owner') +yapi_query = namedtuple('yapi_query', 'vars dict') + + + + + + + + + + + + + + + + + + From 3699a715ced89f1d9251217b6d5c03abe58a5a8d Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Sun, 23 Dec 2018 15:38:56 +0000 Subject: [PATCH 13/14] yapi --- packages/python/pybips.c | 150 ++++----------------------- packages/python/pypreds.c | 2 +- packages/python/swig/prolog/yapi.yap | 50 +++++---- pl/control.yap | 24 +++-- pl/undefined.yap | 1 - 5 files changed, 56 insertions(+), 171 deletions(-) diff --git a/packages/python/pybips.c b/packages/python/pybips.c index 986162d01..18a26bea8 100644 --- a/packages/python/pybips.c +++ b/packages/python/pybips.c @@ -601,132 +601,6 @@ static long get_len_of_range(long lo, long hi, long step) { {"A29", NULL}, {"A29", NULL}, {"A30", NULL}, {"A31", NULL}, {"A32", NULL}, {NULL, NULL}}; - static PyObject *structseq_str(PyStructSequence *obj ) { - -/* buffer and type size were chosen well considered. */ -#define REPR_BUFFER_SIZE 512 -#define TYPE_MAXSIZE 100 - - bool removelast = false; - PyTypeObject *typ = Py_TYPE(obj); - const char *type_name = typ->tp_name; - 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 = - strnlen(type_name, TYPE_MAXSIZE); - strncpy(pbuf, type_name, len); - pbuf += len; - *pbuf++ = '('; - - for (i = 0; i < ((PyStructSequence *)obj)->ob_base.ob_size; i++) { - PyObject *val, *repr; - const char *crepr; - - val = PyStructSequence_GET_ITEM(obj, i); - repr = PyObject_Str(val); - if (repr == NULL) - return Py_None; - crepr = PyUnicode_AsUTF8(repr); - if (crepr == NULL) { - Py_DECREF(repr); - return Py_None; - } - - /* + 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) { - -/* 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); - const char *type_name = typ->tp_name; - 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 = - strnlen(type_name, TYPE_MAXSIZE); - strncpy(pbuf, type_name, len); - pbuf += len; - *pbuf++ = '('; - - for (i = 0; i < ((PyStructSequence *)obj)->ob_base.ob_size; i++) { - PyObject *val, *repr; - const 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; - } - } - if (removelast) { - /* overwrite last ", " */ - pbuf -= 2; - } - *pbuf++ = ')'; - *pbuf = '\0'; - - return PyUnicode_FromString(buf); -} #endif static bool legal_symbol(const char *s) { @@ -761,8 +635,9 @@ PyObject *term_to_nametuple(const char *s, arity_t arity, PyObject *tuple) { typp = (PyTypeObject *)d; } else { PyStructSequence_Desc *desc = PyMem_Calloc(sizeof(PyStructSequence_Desc), 1); - desc->name = PyMem_Malloc(strlen(s) + 1); - strcpy(desc->name, s); + char *tnp; + desc->name = tnp = PyMem_Malloc(strlen(s) + 1); + strcpy(tnp, s); desc->doc = "YAPTerm"; desc->fields = pnull; desc->n_in_sequence = arity; @@ -773,7 +648,7 @@ PyObject *term_to_nametuple(const char *s, arity_t arity, PyObject *tuple) { return NULL; typp->tp_traverse = NULL; typp->tp_flags |= - Py_TPFLAGS_TUPLE_SUBCLASS| + // Py_TPFLAGS_TUPLE_SUBCLASS| Py_TPFLAGS_BASETYPE| Py_TPFLAGS_HEAPTYPE; // don't do this: we cannot add a type as an atribute. @@ -783,8 +658,6 @@ PyObject *term_to_nametuple(const char *s, arity_t arity, PyObject *tuple) { Py_INCREF(key); Py_INCREF(typp); } - typp->tp_repr = structseq_repr; - typp->tp_str = structseq_str; } PyObject *o = PyStructSequence_New(typp); Py_INCREF(typp); @@ -915,7 +788,14 @@ PyObject *compound_to_pytree(term_t t, PyObject *context, bool cvt) { PyTuple_SET_ITEM(n, 1, out); return n; } - return term_to_nametuple(s, arity, out); + if (cvt) + return term_to_nametuple(s, arity, out); + else { + PyObject *rc = PyTuple_New(2); + PyTuple_SetItem(rc, 0, PyUnicode_FromString(s)); + PyTuple_SetItem(rc, 1, out); + return rc; + } } } @@ -1146,7 +1026,13 @@ PyObject *compound_to_pyeval(term_t t, PyObject *context, bool cvt) { // PyObject_Print(rc, stderr, 0); // DebugPrintf("CallObject %p\n", rc); } else { + if (cvt) rc = term_to_nametuple(s, arity, pArgs); + else { + rc = PyTuple_New(2); + PyTuple_SetItem(rc, 0, ys); + PyTuple_SetItem(rc, 1, pArgs); + } } return rc; diff --git a/packages/python/pypreds.c b/packages/python/pypreds.c index 20cf338c8..9b357ea6a 100644 --- a/packages/python/pypreds.c +++ b/packages/python/pypreds.c @@ -31,7 +31,7 @@ static foreign_t python_represent( term_t name, term_t tobj) { term_t stackp = python_acquire_GIL(); PyObject *e; - e = term_to_python(tobj, false, NULL, true); + e = term_to_python(tobj, false, NULL, false); if (e == NULL) { python_release_GIL(stackp); pyErrorAndReturn(false); diff --git a/packages/python/swig/prolog/yapi.yap b/packages/python/swig/prolog/yapi.yap index dbf909df0..a125f02e6 100644 --- a/packages/python/swig/prolog/yapi.yap +++ b/packages/python/swig/prolog/yapi.yap @@ -74,48 +74,46 @@ argi(N,I,I1) :- python_query( Caller, String ) :- atomic_to_term( String, Goal, VarNames ), - query_to_answer( Goal, VarNames, Status, Bindings), + query_to_answer( Goal, _, Status, VarNames, Bindings), Caller.port := Status, - write_query_answer( Bindings ), - answer := {}, - foldl(ground_dict(answer), Bindings, [], Ts), - term_variables( Ts, Hidden), - foldl(bv, Hidden , 0, _), + output(Caller, Bindings). + +output( _, Bindings ) :- + write_query_answer( Bindings ), + fail. +output( Caller, Bindings ) :- + answer := {}, + foldl(ground_dict(answer), Bindings, [], Ts), + term_variables( Ts, Hidden), + foldl(bv, Hidden , 0, _), maplist(into_dict(answer),Ts), Caller.answer := json.dumps(answer), - S := Caller.answer, -format(user_error, '~nor ~s~n~n',S). - + S := Caller.answer, + format(user_error, '~nor ~s~n~n',S), + fail. +output(_Caller, _Bindings). bv(V,I,I1) :- atomic_concat(['__',I],V), I1 is I+1. into_dict(D,V0=T) :- - D[V0] := T. + python_represents(D[V0], T). /** * */ -ground_dict(_Dict, var([V,V]), I, I) :- +ground_dict(_Dict,var([_V]), I, I) :- !. -ground_dict(Dict, nonvar([V0|Vs], T),I0, [V0=T| I0]) :- +ground_dict(_Dict,var([V,V]), I, I) :- + !. +ground_dict(Dict, nonvar([V0|Vs],T),I0, [V0=T| I0]) :- !, - ground_dict( Dict, var([V0|Vs]), I0, I0). -ground_dict(Dict, var([V0,V|Vs]), I, I) :- + ground_dict(Dict, var([V0|Vs]),I0, I0). +ground_dict(Dict, var([V0,V1|Vs]), I, I) :- !, - Dict[V]=V0, - ground_dict( Dict, var([V0|Vs]), I, I). -ground_dict(_, _, _, _). + Dict[V1] := V0, + ground_dict(Dict, var([V0|Vs]), I, I). -bound_dict(Dict, nonvar([V0|Vs], T)) :- - !, - Dict[V0] := T, - bound_dict( Dict, var([V0|Vs])). -bound_dict(Dict, var([V0,V|Vs])) :- - !, - Dict[V] := V0, - bound_dict( Dict, var([V0|Vs])). -bound_dict(_, _). diff --git a/pl/control.yap b/pl/control.yap index c00c55652..19d7d3c4d 100644 --- a/pl/control.yap +++ b/pl/control.yap @@ -389,20 +389,22 @@ version(T) :- fail. '$set_toplevel_hook'(_). -query_to_answer(G, V, Status, Vs) :- - gated_call( true, (G,'$delayed_goals'(G, V, Vs, LGs, _DCP)), Status, '$answer'( Status, LGs, Vs ) ). +query_to_answer(G, V, Status, Vs, Bindings ) :- + gated_call( true, (G,'$delayed_goals'(G, V, Vs, LGs, _DCP)), Status, '$answer'( Status, LGs, Vs, Bindings ) ). -'$answer'( exit, LGs, Vs) :- - !. %, -%'$process_answer'(Vs, LGs). -'$answer'( answer, LGs, Vs) :- - !. %, -% '$process_answer'(Vs, LGs, Bindings). -'$answer'(!, _, _). -'$answer'(fail,_,_). +'$answer'( exit, LGs, Vs, Bindings ) :- + !, + '$sort'(Vs, NVs), + '$prep_answer_var_by_var'(NVs, Bindings , LGs). +'$answer'( answer, LGs, Vs, Bindings) :- + !, + '$sort'(Vs, NVs), + '$prep_answer_var_by_var'(NVs, Bindings , LGs). +'$answer'(!, _, _,_). +'$answer'(fail,_,_,_). '$answer'(exception(E),_,_,_) :- '$LoopError'(E,error). -'$answer'(external_exception(_),_,_). +'$answer'(external_exception(_),_,_,_). %% @} diff --git a/pl/undefined.yap b/pl/undefined.yap index fd2d14731..3c11f1a1d 100644 --- a/pl/undefined.yap +++ b/pl/undefined.yap @@ -113,7 +113,6 @@ undefined_query(G0, M0, Cut) :- % undef handler '$undefp'([M0|G0],_) :- -start_low_level_trace, % make sure we do not loop on undefined predicates setup_call_catcher_cleanup( '$undef_set'(Action,Debug,Current), From 3f1c2352f300ca71f4f517eccc1d171ad7e11bf2 Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Fri, 28 Dec 2018 17:44:28 +0000 Subject: [PATCH 14/14] jpl fixes --- CMakeLists.txt | 4 ++-- packages/jpl/src/c/jpl.c | 29 +++++++++++++++++------------ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b31c68d8..10fe55339 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -855,8 +855,8 @@ if (WITH_JAVA) if (APPLE) set(CMAKE_MACOSX_RPATH 1) find_library (JLI jli ${JAVA_AWT_DIR}/jli) - find_library (JAL JavaApplicationLauncher FRAMEWORK ONLY PATH /System/Library/PrivateFrameworks) - find_library (JL JavaLaunching FRAMEWORK ONLY PATH /System/Library/PrivateFrameworks) + #find_library (JAL JavaApplicationLauncher FRAMEWORK ONLY PATH /System/Library/PrivateFrameworks) + #find_library (JL JavaLaunching FRAMEWORK ONLY PATH /System/Library/PrivateFrameworks) list(APPEND CMAKE_INSTALL_RPATH ${JAVA_AWT_DIR}/jli) list(APPEND JNI_LIBRARIES ${JLI};${JAL};${JL}) endif() diff --git a/packages/jpl/src/c/jpl.c b/packages/jpl/src/c/jpl.c index 1f05f8ca9..ae7d24eb0 100755 --- a/packages/jpl/src/c/jpl.c +++ b/packages/jpl/src/c/jpl.c @@ -48,6 +48,8 @@ refactoring (trivial): #define JPL_C_LIB_VERSION_PATCH 4 #define JPL_C_LIB_VERSION_STATUS "alpha" +#define JPL_DEBUG + #ifndef JPL_DEBUG /*#define DEBUG(n, g) ((void)0) */ #define DEBUG_LEVEL 4 @@ -640,7 +642,7 @@ static JNIEnv* jni_env(void) /* economically gets a JNIEnv pointer, valid for this thread */ { JNIEnv *env; - switch( (*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_8) ) + switch( (*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_9) ) { case JNI_OK: return env; case JNI_EDETACHED: @@ -1819,20 +1821,20 @@ jni_create_jvm_c( char *cpoptp; JavaVMOption opt[MAX_JVM_OPTIONS]; int r; - jint n; + jint n = 1; int optn = 0; JNIEnv *env; JPL_DEBUG(1, Sdprintf( "[creating JVM with 'java.class.path=%s']\n", classpath)); - vm_args.version = JNI_VERSION_1_6; /* "Java 1.2 please" */ + vm_args.version = JNI_VERSION_1_6zzzz; /* "Java 1.2 please" */ if ( classpath ) { - cpoptp = (char *)malloc(strlen(classpath)+20); - strcpy( cpoptp, "-Djava.class.path="); /* was cpopt */ - strcat( cpoptp, classpath); /* oughta check length... */ - vm_args.options = opt; - opt[optn].optionString = cpoptp; /* was cpopt */ - optn++; + cpoptp = (char *)malloc(strlen(classpath) + strlen("-Djava.class.path=")+1); + strcpy(cpoptp, "-Djava.class.path="); /* was cpopt */ + strcat(cpoptp, classpath); /* oughta check length... */ + vm_args.options = opt; + opt[optn].optionString = cpoptp; /* was cpopt */ + optn++; } /* opt[optn++].optionString = "-Djava.compiler=NONE"; */ /* opt[optn].optionString = "exit"; // I don't understand this yet... */ @@ -1841,10 +1843,12 @@ jni_create_jvm_c( /* opt[optn++].extraInfo = jvm_abort; // this function has been moved to jpl_extras.c */ /* opt[optn++].optionString = "-Xcheck:jni"; // extra checking of JNI calls */ #if __YAP_PROLOG__ - opt[optn++].optionString = "-Xmx512m"; // give java enough space + opt[optn].optionString = malloc(strlen("-Xmx512m")+1); // give java enough space + strcpy(opt[optn++].optionString,"-Xmx512m"); // give java enough space #if defined(__APPLE__) - // I can't make jpl work with AWT graphics, without creating the extra thread. - opt[optn++].optionString = "-Djava.awt.headless=true"; + // I can't make jpl work with AWT graphics, without creating the extra thread. + opt[optn].optionString = malloc(strlen("-Djava.awt.headless=true") + 1); // give java enough space + strcpy(opt[optn++].optionString, "-Djava.awt.headless=true"); // give java enough space #endif // opt[optn++].optionString = "-XstartOnFirstThread"; #endif @@ -1853,6 +1857,7 @@ jni_create_jvm_c( /* opt[optn++].extraInfo = fprintf; // no O/P, then SEGV */ /* opt[optn++].extraInfo = xprintf; // one message, then SEGV */ /* opt[optn++].optionString = "-verbose:jni"; */ + opt[optn].optionString = NULL; if ( jvm_dia != NULL ) {