From 18af47bdde063463301aede8c34ed7a463cc059b Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Fri, 19 May 2017 09:56:37 +0100 Subject: [PATCH] Jupyter --- C/adtdefs.c | 6 +- C/c_interface.c | 16 +- C/cdmgr.c | 20 +- CXX/yapdb.hh | 14 +- CXX/yapi.cpp | 478 +++++++++--------- CXX/yapq.hh | 130 +++-- include/YapInterface.h | 2 + packages/python/swig/CMakeLists.txt | 6 +- packages/python/swig/yapi.py | 34 +- packages/python/swig/yapi.yap | 111 ++-- .../yap_kernel/yap_kernel/interactiveshell.py | 93 ++-- .../python/yap_kernel/yap_kernel/yapkernel.py | 1 + pl/absf.yap | 4 +- 13 files changed, 484 insertions(+), 431 deletions(-) diff --git a/C/adtdefs.c b/C/adtdefs.c index f067d5965..755ce5c41 100755 --- a/C/adtdefs.c +++ b/C/adtdefs.c @@ -493,8 +493,7 @@ Prop Yap_GetPredPropByAtom(Atom at, Term cur_mod) return (p0); } -inline static Prop GetPredPropByAtomHavingLockInThisModule(AtomEntry *ae, - Term cur_mod) +inline static Prop GetPredPropByAtomHavingLockInThisModule(AtomEntry *ae, Term cur_mod) /* get predicate entry for ap/arity; create it if neccessary. */ { Prop p0; @@ -528,14 +527,15 @@ Prop Yap_GetPredPropByAtomInThisModule(Atom at, Term cur_mod) return (p0); } + Prop Yap_GetPredPropByFunc(Functor f, Term cur_mod) /* get predicate entry for ap/arity; */ { Prop p0; - FUNC_READ_LOCK(f); p0 = GetPredPropByFuncHavingLock(f, cur_mod); + FUNC_READ_UNLOCK(f); return (p0); } diff --git a/C/c_interface.c b/C/c_interface.c index 6196e8c5c..129d3c25e 100755 --- a/C/c_interface.c +++ b/C/c_interface.c @@ -3396,10 +3396,18 @@ X_API Functor YAP_IntToFunctor(Int i) { return TR_Functors[i]; } X_API void *YAP_shared(void) { return LOCAL_shared; } -void yap_init(void) {} + X_API PredEntry *YAP_TopGoal(void) + { + YAP_Functor f = Yap_MkFunctor(Yap_LookupAtom("yap_query"),3); + Term tmod = MkAtomTerm(Yap_LookupAtom("yapi")); + PredEntry *p = RepPredProp(Yap_GetPredPropByFunc(f, tmod)); + return p; + } + + void yap_init(void) {} #endif // C_INTERFACE_C -/** -@} -*/ + /** + @} + */ diff --git a/C/cdmgr.c b/C/cdmgr.c index 11f097663..a903380e1 100644 --- a/C/cdmgr.c +++ b/C/cdmgr.c @@ -1647,6 +1647,14 @@ bool Yap_constPred(PredEntry *p) { pred_flags_t pflags; pflags = p->PredFlags; + if (pflags & + ((UserCPredFlag | CArgsPredFlag | NumberDBPredFlag | AtomDBPredFlag | + TestPredFlag | AsmPredFlag | CPredFlag | BinaryPredFlag))) + return true; + + if (p->PredFlags & + (SysExportPredFlag | MultiFileFlag | DynamicPredFlag | LogUpdatePredFlag)) + return false; if (Yap_isSystemModule(p->ModuleOfPred)) { if (p->cs.p_code.NOfClauses == 0) { p->src.OwnerFile = Yap_source_file_name(); @@ -1656,15 +1664,7 @@ bool Yap_constPred(PredEntry *p) { return false; } } - if (pflags & - ((UserCPredFlag | CArgsPredFlag | NumberDBPredFlag | AtomDBPredFlag | - TestPredFlag | AsmPredFlag | CPredFlag | BinaryPredFlag))) - return true; - - if (p->PredFlags & - (SysExportPredFlag | MultiFileFlag | DynamicPredFlag | LogUpdatePredFlag)) - return false; - + return false; } @@ -1719,7 +1719,6 @@ bool Yap_addclause(Term t, yamop *cp, Term tmode, Term mod, Term *t4ref) at = NameOfFunctor(f); p = RepPredProp(PredPropByFunc(f, mod)); } - Yap_PutValue(AtomAbol, TermNil); PELOCK(20, p); /* we are redefining a prolog module predicate */ if (Yap_constPred(p)) { @@ -1727,6 +1726,7 @@ bool Yap_addclause(Term t, yamop *cp, Term tmode, Term mod, Term *t4ref) UNLOCKPE(30, p); return false; } + Yap_PutValue(AtomAbol, TermNil); pflags = p->PredFlags; /* we are redefining a prolog module predicate */ if (pflags & MegaClausePredFlag) { diff --git a/CXX/yapdb.hh b/CXX/yapdb.hh index cd617862b..aeda8fb70 100644 --- a/CXX/yapdb.hh +++ b/CXX/yapdb.hh @@ -46,7 +46,7 @@ class YAPModule; class YAPModule : protected YAPAtomTerm { friend class YAPPredicate; friend class YAPModuleProp; - YAPModule(Term t) : YAPAtomTerm(t){}; + YAPModule(YAP_Term t) : YAPAtomTerm(t){}; Term t() { return gt(); } Term curModule() { CACHE_REGS return Yap_CurrentModule(); } @@ -138,6 +138,11 @@ protected: PredEntry *asPred() { return ap; }; +/// Empty constructor for predicates + /// + /// Just do nothing. + inline YAPPredicate() { + } /// String constructor for predicates /// /// It also communicates the array of arguments t[] @@ -181,6 +186,13 @@ protected: /// inline YAPPredicate(PredEntry *pe) { ap = pe; } + /// Functor constructor for predicates, is given a specific module. + /// This version avoids manufacturing objects + inline YAPPredicate(Functor f, Term mod) { + ap = RepPredProp(PredPropByFunc(f, mod)); + } + + public: /// Functor constructor for predicates diff --git a/CXX/yapi.cpp b/CXX/yapi.cpp index 031138907..6c2ec4ed1 100644 --- a/CXX/yapi.cpp +++ b/CXX/yapi.cpp @@ -435,16 +435,7 @@ void YAPQuery::openQuery(Term t) XREGS[i + 1] = ts[i]; } } - // oq = LOCAL_execution; - // LOCAL_execution = this; - q_open = true; - q_state = 0; - q_flags = true; // PL_Q_PASS_EXCEPTION; - - q_p = P; - q_cp = CP; - // make sure this is safe - q_handles = LOCAL_CurSlot; + setNext(); } bool YAPEngine::call(YAPPredicate ap, YAPTerm ts[]) @@ -833,6 +824,7 @@ void Yap_displayWithJava(int c) #endif + void YAPEngine::doInit(YAP_file_type_t BootMode) { if ((BootMode = YAP_Init(&engine_args->init_args)) == YAP_FOUND_BOOT_ERROR) @@ -852,228 +844,264 @@ void YAPEngine::doInit(YAP_file_type_t BootMode) do_init_python(); #endif - - YAPQuery initq = YAPQuery(YAPAtom("$init_system")); - if (initq.next()) - { - initq.cut(); - } - else - { - // should throw exception - } + YAP_Functor f = YAP_MkFunctor(YAP_LookupAtom("$init_system"), 3); + YAP_PredEntryPtr p = YAP_FunctorToPred( f ); + YAPQuery initq = YAPQuery(YAPPredicate(p), nullptr); + if (initq.next()) + { + initq.cut(); + } + else + { + // should throw exception + } } YAPEngine::YAPEngine(int argc, char *argv[], - YAPCallback *cb) - : _callback(0) { // a single engine can be active + YAPCallback *cb) + : _callback(0) { // a single engine can be active - YAP_file_type_t BootMode; - engine_args = new YAPEngineArgs(); - BootMode = YAP_parse_yap_arguments(argc, argv, &engine_args->init_args); - // delYAPCallback()b - // if (cb) - // setYAPCallback(cb); - doInit(BootMode); -} - - -YAPPredicate::YAPPredicate(YAPAtom at) -{ - CACHE_REGS - ap = RepPredProp(PredPropByAtom(at.a, Yap_CurrentModule())); -} - -YAPPredicate::YAPPredicate(YAPAtom at, uintptr_t arity) -{ - CACHE_REGS - if (arity) - { - Functor f = Yap_MkFunctor(at.a, arity); - ap = RepPredProp(PredPropByFunc(f, Yap_CurrentModule())); - } - else - { - ap = RepPredProp(PredPropByAtom(at.a, Yap_CurrentModule())); - } -} - -/// auxiliary routine to find a predicate in the current module. -PredEntry *YAPPredicate::getPred(YAPTerm &tt, Term *&outp) -{ - CACHE_REGS - Term m = Yap_CurrentModule(), t = tt.term(); - t = Yap_StripModule(t, &m); - if (IsVarTerm(t) || IsNumTerm(t)) - { - if (IsVarTerm(t)) - Yap_ThrowError(INSTANTIATION_ERROR, tt.term(), 0); - else if (IsNumTerm(t)) - Yap_ThrowError(TYPE_ERROR_CALLABLE, tt.term(), 0); - throw YAPError(); - } - tt.put(t); - if (IsAtomTerm(t)) - { - ap = RepPredProp(PredPropByAtom(AtomOfTerm(t), m)); - outp = (Term *)NULL; - return ap; - } - else if (IsPairTerm(t)) - { - Term ts[2]; - ts[0] = t; - ts[1] = m; - t = Yap_MkApplTerm(FunctorCsult, 2, ts); - tt.put(t); - outp = RepAppl(t) + 1; - } - Functor f = FunctorOfTerm(t); - if (IsExtensionFunctor(f)) - { - Yap_ThrowError(TYPE_ERROR_CALLABLE, t, 0); - } - else - { - ap = RepPredProp(PredPropByFunc(f, m)); - outp = RepAppl(t) + 1; - } - return ap; -} - -X_API bool YAPPrologPredicate::assertClause(YAPTerm cl, bool last, - YAPTerm source) -{ - CACHE_REGS - - RECOVER_MACHINE_REGS(); - Term tt = cl.gt(); - Term sourcet; - Term ntt = cl.gt(); - if (source.initialized()) - sourcet = source.gt(); - else - sourcet = TermZERO; - yamop *codeaddr = Yap_cclause(tt, ap->ArityOfPE, Yap_CurrentModule(), - sourcet); /* vsc: give the number of arguments - to cclause in case there is overflow */ - if (LOCAL_ErrorMessage) - { - RECOVER_MACHINE_REGS(); - return false; - } - Term *tref = &ntt; - if (Yap_addclause(ntt, codeaddr, (last ? TermAssertz : TermAsserta), - Yap_CurrentModule(), tref)) - { - RECOVER_MACHINE_REGS(); - } - return tref; -} - -bool YAPPrologPredicate::assertFact(YAPTerm *cl, bool last) -{ - CACHE_REGS - arity_t i; - RECOVER_MACHINE_REGS(); - Term tt = AbsAppl(HR); - *HR++ = (CELL)(ap->FunctorOfPred); - for (i = 0; i < ap->ArityOfPE; i++, cl++) - *HR++ = cl->gt(); - yamop *codeaddr = Yap_cclause(tt, ap->ArityOfPE, Yap_CurrentModule(), - tt); /* vsc: give the number of arguments - to cclause in case there is overflow */ - if (LOCAL_ErrorMessage) - { - RECOVER_MACHINE_REGS(); - return false; - } - Term *tref = &tt; - if (Yap_addclause(tt, codeaddr, (last ? TermAssertz : TermAsserta), - Yap_CurrentModule(), tref)) - { - RECOVER_MACHINE_REGS(); - } - return tref; -} - -void *YAPPrologPredicate::retractClause(YAPTerm skeleton, bool all) -{ - return 0; -} - -std::string YAPError::text() -{ - char buf[256]; - std::string s = ""; - if (LOCAL_ActiveError->errorFunction) - { - s += LOCAL_ActiveError->errorFile; - s += ":"; - sprintf(buf, "%ld", (long int)LOCAL_ActiveError->errorLine); - s += buf; - s += ":0 in C-code"; - } - if (LOCAL_ActiveError->prologPredLine) - { - s += "\n"; - s += LOCAL_ActiveError->prologPredFile->StrOfAE; - s += ":"; - sprintf(buf, "%ld", (long int)LOCAL_ActiveError->prologPredLine); - s += buf; // std::to_string(LOCAL_ActiveError->prologPredLine) ; - // YAPIntegerTerm(LOCAL_ActiveError->prologPredLine).text(); - s += ":0 "; - s += LOCAL_ActiveError->prologPredModule; - s += ":"; - s += (LOCAL_ActiveError->prologPredName)->StrOfAE; - s += "/"; - sprintf(buf, "%ld", (long int)LOCAL_ActiveError->prologPredArity); - s += // std::to_string(LOCAL_ActiveError->prologPredArity); - buf; - } - s += " error "; - if (LOCAL_ActiveError->classAsText != nullptr) - s += LOCAL_ActiveError->classAsText->StrOfAE; - s += "."; - s += LOCAL_ActiveError->errorAsText->StrOfAE; - s += ".\n"; - if (LOCAL_ActiveError->errorTerm) - { - Term t = LOCAL_ActiveError->errorTerm->Entry; - if (t) - { - s += "error term is: "; - s += YAPTerm(t).text(); - s += "\n"; + YAP_file_type_t BootMode; + engine_args = new YAPEngineArgs(); + BootMode = YAP_parse_yap_arguments(argc, argv, &engine_args->init_args); + // delYAPCallback()b + // if (cb) + // setYAPCallback(cb); + doInit(BootMode); } - } - printf("%s\n", s.c_str()); - return s.c_str(); -} -void YAPEngine::reSet() -{ - /* ignore flags for now */ - BACKUP_MACHINE_REGS(); - Yap_RebootHandles(worker_id); - while (B->cp_b) - B = B->cp_b; - P = FAILCODE; - Yap_exec_absmi(true, YAP_EXEC_ABSMI); - /* recover stack space */ - HR = B->cp_h; - TR = B->cp_tr; + + YAPPredicate::YAPPredicate(YAPAtom at) + { + CACHE_REGS + ap = RepPredProp(PredPropByAtom(at.a, Yap_CurrentModule())); + } + + YAPPredicate::YAPPredicate(YAPAtom at, uintptr_t arity) + { + CACHE_REGS + if (arity) + { + Functor f = Yap_MkFunctor(at.a, arity); + ap = RepPredProp(PredPropByFunc(f, Yap_CurrentModule())); + } + else + { + ap = RepPredProp(PredPropByAtom(at.a, Yap_CurrentModule())); + } + } + + /// auxiliary routine to find a predicate in the current module. + PredEntry *YAPPredicate::getPred(YAPTerm &tt, Term *&outp) + { + CACHE_REGS + Term m = Yap_CurrentModule(), t = tt.term(); + t = Yap_StripModule(t, &m); + if (IsVarTerm(t) || IsNumTerm(t)) + { + if (IsVarTerm(t)) + Yap_ThrowError(INSTANTIATION_ERROR, tt.term(), 0); + else if (IsNumTerm(t)) + Yap_ThrowError(TYPE_ERROR_CALLABLE, tt.term(), 0); + throw YAPError(); + } + tt.put(t); + if (IsAtomTerm(t)) + { + ap = RepPredProp(PredPropByAtom(AtomOfTerm(t), m)); + outp = (Term *)NULL; + return ap; + } + else if (IsPairTerm(t)) + { + Term ts[2]; + ts[0] = t; + ts[1] = m; + t = Yap_MkApplTerm(FunctorCsult, 2, ts); + tt.put(t); + outp = RepAppl(t) + 1; + } + Functor f = FunctorOfTerm(t); + if (IsExtensionFunctor(f)) + { + Yap_ThrowError(TYPE_ERROR_CALLABLE, t, 0); + } + else + { + ap = RepPredProp(PredPropByFunc(f, m)); + outp = RepAppl(t) + 1; + } + return ap; + } + + X_API bool YAPPrologPredicate::assertClause(YAPTerm cl, bool last, + YAPTerm source) + { + CACHE_REGS + + RECOVER_MACHINE_REGS(); + Term tt = cl.gt(); + Term sourcet; + Term ntt = cl.gt(); + if (source.initialized()) + sourcet = source.gt(); + else + sourcet = TermZERO; + yamop *codeaddr = Yap_cclause(tt, ap->ArityOfPE, Yap_CurrentModule(), + sourcet); /* vsc: give the number of arguments + to cclause in case there is overflow */ + if (LOCAL_ErrorMessage) + { + RECOVER_MACHINE_REGS(); + return false; + } + Term *tref = &ntt; + if (Yap_addclause(ntt, codeaddr, (last ? TermAssertz : TermAsserta), + Yap_CurrentModule(), tref)) + { + RECOVER_MACHINE_REGS(); + } + return tref; + } + + bool YAPPrologPredicate::assertFact(YAPTerm *cl, bool last) + { + CACHE_REGS + arity_t i; + RECOVER_MACHINE_REGS(); + Term tt = AbsAppl(HR); + *HR++ = (CELL)(ap->FunctorOfPred); + for (i = 0; i < ap->ArityOfPE; i++, cl++) + *HR++ = cl->gt(); + yamop *codeaddr = Yap_cclause(tt, ap->ArityOfPE, Yap_CurrentModule(), + tt); /* vsc: give the number of arguments + to cclause in case there is overflow */ + if (LOCAL_ErrorMessage) + { + RECOVER_MACHINE_REGS(); + return false; + } + Term *tref = &tt; + if (Yap_addclause(tt, codeaddr, (last ? TermAssertz : TermAsserta), + Yap_CurrentModule(), tref)) + { + RECOVER_MACHINE_REGS(); + } + return tref; + } + + void *YAPPrologPredicate::retractClause(YAPTerm skeleton, bool all) + { + return 0; + } + + std::string YAPError::text() + { + char buf[256]; + std::string s = ""; + if (LOCAL_ActiveError->errorFunction) + { + s += LOCAL_ActiveError->errorFile; + s += ":"; + sprintf(buf, "%ld", (long int)LOCAL_ActiveError->errorLine); + s += buf; + s += ":0 in C-code"; + } + if (LOCAL_ActiveError->prologPredLine) + { + s += "\n"; + s += LOCAL_ActiveError->prologPredFile->StrOfAE; + s += ":"; + sprintf(buf, "%ld", (long int)LOCAL_ActiveError->prologPredLine); + s += buf; // std::to_string(LOCAL_ActiveError->prologPredLine) ; + // YAPIntegerTerm(LOCAL_ActiveError->prologPredLine).text(); + s += ":0 "; + s += LOCAL_ActiveError->prologPredModule; + s += ":"; + s += (LOCAL_ActiveError->prologPredName)->StrOfAE; + s += "/"; + sprintf(buf, "%ld", (long int)LOCAL_ActiveError->prologPredArity); + s += // std::to_string(LOCAL_ActiveError->prologPredArity); + buf; + } + s += " error "; + if (LOCAL_ActiveError->classAsText != nullptr) + s += LOCAL_ActiveError->classAsText->StrOfAE; + s += "."; + s += LOCAL_ActiveError->errorAsText->StrOfAE; + s += ".\n"; + if (LOCAL_ActiveError->errorTerm) + { + Term t = LOCAL_ActiveError->errorTerm->Entry; + if (t) + { + s += "error term is: "; + s += YAPTerm(t).text(); + s += "\n"; + } + } + printf("%s\n", s.c_str()); + return s.c_str(); + } + + void YAPEngine::reSet() + { + /* ignore flags for now */ + BACKUP_MACHINE_REGS(); + Yap_RebootHandles(worker_id); + while (B->cp_b) + B = B->cp_b; + P = FAILCODE; + Yap_exec_absmi(true, YAP_EXEC_ABSMI); + /* recover stack space */ + HR = B->cp_h; + TR = B->cp_tr; #ifdef DEPTH_LIMIT - DEPTH = B->cp_depth; + DEPTH = B->cp_depth; #endif /* DEPTH_LIMIT */ - YENV = ENV = B->cp_env; + YENV = ENV = B->cp_env; - RECOVER_MACHINE_REGS(); -} + RECOVER_MACHINE_REGS(); + } -YAPError::YAPError(yap_error_number id, YAPTerm culprit, std::string txt) -{ - ID = id; - goal = culprit.text(); - info = txt; -} + YAPError::YAPError(yap_error_number id, YAPTerm culprit, std::string txt) + { + ID = id; + goal = culprit.text(); + info = txt; + } + + Term YAPEngine::top_level( std::string s) + + { + + /// parse string s and make term with var names + /// available. + Term tp; + ARG1 = YAP_ReadBuffer(s.data(), &tp); + ARG2 = tp; + ARG3 = MkVarTerm(); + YAPPredicate p = YAPPredicate(YAP_TopGoal()); + YAPQuery *Q = new YAPQuery(p,0); + if (Q->next()) { + Term ts[2]; + ts[0]= MkAddressTerm(Q); + ts[1]= ARG3; + return YAP_MkApplTerm(YAP_MkFunctor(YAP_LookupAtom("t"), 2), 2, ts); + } + YAPError(); + return 0; + } + + Term YAPEngine::next_answer(YAPQuery * &Q) { + + /// parse string s and make term with var names + /// available. + if (Q->next()) { + Term ts[2]; + ts[0]= MkAddressTerm(Q); + ts[1]= ARG3; + return YAP_MkApplTerm(YAP_MkFunctor(YAP_LookupAtom("t"), 2), 2, ts); + } + return 0; + } diff --git a/CXX/yapq.hh b/CXX/yapq.hh index 1bf9fb999..223c86beb 100644 --- a/CXX/yapq.hh +++ b/CXX/yapq.hh @@ -2,7 +2,7 @@ /** * @file yapq.hh * - * @defgroup yap-cplus-query-hanadlinge Query Handling in the YAP interface. + * @defgroup yap-cplus-query-handling Query Handling in the YAP interface. * @brief Engine and Query Management * * @ingroup yap-cplus-interface @@ -46,9 +46,24 @@ class YAPQuery : public YAPPredicate // temporaries Term tnames, tgoal ; + inline void setNext() { // oq = LOCAL_execution; + // LOCAL_execution = this; + q_open = true; + q_state = 0; + q_flags = true; // PL_Q_PASS_EXCEPTION; + + q_p = P; + q_cp = CP; + // make sure this is safe + q_handles = LOCAL_CurSlot; +} + void openQuery(Term t); + public: +YAPQuery() { +}; /// main constructor, uses a predicate and an array of terms /// /// It is given a YAPPredicate _p_ , and an array of terms that must have at @@ -74,63 +89,68 @@ public: /// goal. inline YAPQuery(const char *s) : YAPPredicate(s, tgoal, tnames) { - __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "got game %ld", - LOCAL_CurSlot); - if (!ap) - return; - __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "%s", vnames.text()); - goal = YAPTerm(tgoal); - names = YAPPairTerm(tnames); - openQuery(tgoal); + __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "got game %ld", + LOCAL_CurSlot); + if (!ap) + return; + __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "%s", vnames.text()); + goal = YAPTerm(tgoal); + names = YAPPairTerm(tnames); + openQuery(tgoal); }; + // inline YAPQuery() : YAPPredicate(s, tgoal, tnames) + // { + // __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "got game %ld", + // LOCAL_CurSlot); + // if (!ap) + // return; + // __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "%s", vnames.text()); + // goal = YAPTerm(tgoal); + // names = YAPPairTerm(tnames); + // openQuery(tgoal); + // }; /// string constructor with just an atom /// - /// It is given an atom, and a Prolog term that should be a callable - /// goal, say `main`, `init`, `live`. - inline YAPQuery(YAPAtom g) : YAPPredicate(g) - { - goal = YAPAtomTerm(g); - names = YAPPairTerm( ); - openQuery(goal.term()); - }; + /// It i; + ///}; /// set flags for query execution, currently only for exception handling void setFlag(int flag) { q_flags |= flag; } /// reset flags for query execution, currently only for exception handling - void resetFlag(int flag) { q_flags &= ~flag; } - /// first query - /// - /// actually implemented by calling the next(); - inline bool first() { return next(); } - /// ask for the next solution of the current query - /// same call for every solution - bool next(); - /// does this query have open choice-points? - /// or is it deterministic? - bool deterministic(); - /// represent the top-goal - const char *text(); - /// remove alternatives in the current search space, and finish the current - /// query - /// finish the current query: undo all bindings. - void close(); - /// query variables. - void cut(); - Term namedVars() {return names.term(); }; - /// query variables, but copied out - std::vector namedVarsVector() { - return names.listToArray(); }; - /// convert a ref to a binding. - YAPTerm getTerm(yhandle_t t); - /// simple YAP Query; - /// just calls YAP and reports success or failure, Useful when we just - /// want things done, eg YAPCommand("load_files(library(lists), )") - inline bool command() - { - bool rc = next(); - close(); - return rc; - }; +void resetFlag(int flag) { q_flags &= ~flag; } +/// first query +/// +/// actually implemented by calling the next(); +inline bool first() { return next(); } +/// ask for the next solution of the current query +/// same call for every solution +bool next(); +/// does this query have open choice-points? +/// or is it deterministic? +bool deterministic(); +/// represent the top-goal +const char *text(); +/// remove alternatives in the current search space, and finish the current +/// query +/// finish the current query: undo all bindings. +void close(); +/// query variables. +void cut(); +Term namedVars() {return names.term(); }; +/// query variables, but copied out +std::vector namedVarsVector() { + return names.listToArray(); }; +/// convert a ref to a binding. +YAPTerm getTerm(yhandle_t t); +/// simple YAP Query; +/// just calls YAP and reports success or failure, Useful when we just +/// want things done, eg YAPCommand("load_files(library(lists), )") +inline bool command() +{ + bool rc = next(); + close(); + return rc; +}; }; // Java support @@ -408,8 +428,12 @@ public: { return setYapFlag(MkAtomTerm(Yap_LookupAtom(arg.data())), MkAtomTerm(Yap_LookupAtom(path.data()))); }; -}; + + Term top_level( std::string s); + Term next_answer(YAPQuery * &Q); + + }; #endif /* YAPQ_HH */ -/// @} + /// @} diff --git a/include/YapInterface.h b/include/YapInterface.h index bf9be2fc7..11720ba13 100755 --- a/include/YapInterface.h +++ b/include/YapInterface.h @@ -684,6 +684,8 @@ extern X_API YAP_Int YAP_FunctorToInt(YAP_Functor At); extern X_API YAP_Functor YAP_IntToFunctor(YAP_Int i); +extern X_API YAP_PredEntryPtr YAP_TopGoal(void); + #define YAP_InitCPred(N, A, F) YAP_UserCPredicate(N, F, A) __END_DECLS diff --git a/packages/python/swig/CMakeLists.txt b/packages/python/swig/CMakeLists.txt index ed7fb616f..a9593eddc 100644 --- a/packages/python/swig/CMakeLists.txt +++ b/packages/python/swig/CMakeLists.txt @@ -70,9 +70,9 @@ add_custom_target( YAP4PY ALL COMMAND ${CMAKE_COMMAND} -E copy ${pl_library} ${PROLOG_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/yap4py/prolog COMMAND ${CMAKE_COMMAND} -E copy ${pl_boot_library} ${CMAKE_CURRENT_BINARY_DIR}/yap4py/prolog/pl COMMAND ${CMAKE_COMMAND} -E copy ${pl_os_library} ${CMAKE_CURRENT_BINARY_DIR}/yap4py/prolog/os - COMMAND ${PYTHON_EXECUTABLE} setup.py sdist bdist_wheel + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/setup.py sdist bdist_wheel WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} -DEPENDS STARTUP ${dlls} ${PYTHON_SOURCES} ${PROLOG_SOURCES} setup.py ${SWIG_MODULE_Py2YAP_REAL_NAME} ) +DEPENDS STARTUP ${dlls} ${PYTHON_SOURCES} ${PROLOG_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/setup.py ${SWIG_MODULE_Py2YAP_REAL_NAME} ) install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} -m pip install --no-index -f dist yap4py @@ -95,7 +95,7 @@ DEPENDS STARTUP ${dlls} ${PYTHON_SOURCES} ${PROLOG_SOURCES} setup.py ${SWIG_MOD # generate .i from doxygen .xml add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ftdi1_doc.i COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/doxy2swig.py -n - ${CMAKE_BINARY_DIR}/doc/xml/ftdi_8c.xml + ${CMAKE_BINARY_DIR}/doc/xm11l/ftdi_8c.xml ${CMAKE_CURRENT_BINARY_DIR}/ftdi1_doc.i DEPENDS ${CMAKE_BINARY_DIR}/doc/xml/ftdi_8c.xml ) diff --git a/packages/python/swig/yapi.py b/packages/python/swig/yapi.py index dbf98dded..7d227dfcc 100644 --- a/packages/python/swig/yapi.py +++ b/packages/python/swig/yapi.py @@ -3,7 +3,7 @@ import yap import os.path import sys # debugging support. -import pdb +# import pdb from collections import namedtuple yap_lib_path = os.path.dirname(__file__) @@ -12,6 +12,7 @@ use_module = namedtuple( 'use_module', 'file') bindvars = namedtuple( 'bindvars', 'list') library = namedtuple( 'library', 'list') v = namedtuple( '_', 'slot') +yap_query = namedtuple( 'yap_query', 'query owner') def numbervars( engine, l ): @@ -24,8 +25,6 @@ def numbervars( engine, l ): o = o +[i] return o -def query_prolog(engine, s): - def answer(q): try: return q.next() @@ -36,44 +35,29 @@ def query_prolog(engine, s): # # construct a query from a one-line string # q is opaque to Python - q = engine.query(s) + if g0: + q = g0 + else: + q = engine.run_query(s) # vs is the list of variables # you can print it out, the left-side is the variable name, # the right side wraps a handle to a variable # pdb.set_trace() - vs = q.namedVars() - #pdb.set_trace() + # #pdb.set_trace() # atom match either symbols, or if no symbol exists, sttrings, In this case # variable names should match strings #for eq in vs: # if not isinstance(eq[0],str): # print( "Error: Variable Name matches a Python Symbol") # return - ask = True + # ask = True # launch the query while answer(q): - # this new vs should contain bindings to vars - vs= q.namedVars() - if vs != []: - gs = numbervars( engine, vs) - i=0 - # iterate - for eq in gs: - name = eq[0] - binding = eq[1] - # this is tricky, we're going to bind the variables in the term so thay we can - # output X=Y. The Python way is to use dictionares. - #Instead, we use the T function to tranform the Python term back to Prolog - if name != binding: - print(name + " = " + str(binding)) - #ok, that was Prolog code - else: - print("yes") # deterministic = one solution if q.deterministic(): # done q.close() - return + return True, True if ask: s = input("more(;), all(*), no(\\n), python(#) ?").lstrip() if s.startswith(';') or s.startswith('y'): diff --git a/packages/python/swig/yapi.yap b/packages/python/swig/yapi.yap index c6de3df77..2f855427a 100644 --- a/packages/python/swig/yapi.yap +++ b/packages/python/swig/yapi.yap @@ -1,53 +1,76 @@ - %% @file yapi.yap %% @brief support yap shell %% -:- module(yapi, [bindvars/2]). +:- module(yapi, [query/3]). +:- use_module( library(lists) ). :- use_module( library(maplist) ). :- use_module( library(rbtrees) ). -bindvars( [], [] ) :- !. -bindvars( L, NL ) :- - rb_new(T), -% trace, - foldl2( bind, L, NL, T, _ , 0, _), - term_variables(NL, Vs), - foldl( bind_new, Vs, 0, _). + +%% @pred yap_query(0:Goal, + VarList, +OutStream, - Dictionary) +%% @pred yap_query(0:Goal, + VarList, - Dictionary) +%% +%% dictionary, Examples +%% +%% +yap_query( Goal, VarNames, Stream, Dictionary) :- + ( + call(Goal) + *-> + constraints(VarNames, Goal, Stream, Dictionary) + ). + +prolog:yap_query( Goal, VarNames, Dictionary) :- + yap_query( Goal, VarNames, user_output, Dictionary). + +constraints(QVs, Goal, Stream, {Dict}) :- + !, + term_variables(Goal, IVs), + foldl(enumerate, IVs, 0, _Ns), + out(QVs, Stream, Dict). +constraints(_, _, {}) :- + format(' yes.~n', [] ). + +bind_qv(V=V0, Vs, Vs) :- var(V0), !, V0='$VAR'(V). +bind_qv(V=V, Vs, Vs) :- !. +bind_qv(V=S, Vs, [V=S|Vs]). + +enumerate('$VAR'(A), I, I1) :- + enum(I, Chars), + atom_codes(A,[0'_|Chars]), + I1 is I + 1. + +enum(I, [C]) :- + I < 26, + !, C is "A" + I. +enum(I, [C|Cs]) :- + J is I//26, + K is I mod 26, + C is "A" +K, + enum(J, Cs). + +out(Bs, S, _Dict) :- + output(Bs, S), + fail. +out(Bs, _S, Dict) :- + bvs(Bs, Dict). + +v2py(v(I0) = _V, I0, I) :- + !, + I is I0+1. +v2py(v(I0) = v(I0), I0, I) :- + I is I0+1. + +output([V=B], S) :- + format(S, 'a = ~q~n', [V, B]). +output([V=B|Ns], S) :- + format( S, 'a = ~q.~n', [V, B]), + output( Ns, S). -bind(t(_,t(X,Y)), Z, T0, T, N1, N2) :- - !, - bind(X=Y, Z, T0, T, N1, N2). -bind(tuple(_,tuple(X,Y)), Z, T0, T, N1, N2) :- - !, - bind(X=Y, Z, T0, T, N1, N2). -bind(X=Y, X=X, T0, T, N, N) :- - var(Y), - !, - rb_update(T0, Y, X, T). -bind(X = G, X = G, T, T, N0, N0) :- - ground(G), - !. -bind(X = C, X = NC, T, NT, N0, NF) :- - C =.. [N|L], - foldl2(newb, L, NL, T, NT, N0, NF), - NC =.. [N|NL]. - -newb(Y, X, T, T, N, N) :- - var(Y), - rb_lookup(Y, X, T), - !. -newb(Y, X, T, TN, N, NF) :- - var(Y), - !, - rb_insert(Y, T, X, TN), - NF is N+1, - atomic_concat('_',N,X). -newb(Y, Y, T, T, N, N) :- - ground(Y), - !. -newb(Y, X, T, NT, N0, NF) :- - Y =.. [N|L], - foldl2(newb, L, NL, T, NT, N0, NF), - X =.. [N|NL]. + bvs([V=B],{V:B}) :- + !. + bvs([V=B|Ns], (V:B,N)) :- + output( Ns, N). +:- start_low_level_trace. diff --git a/packages/python/yap_kernel/yap_kernel/interactiveshell.py b/packages/python/yap_kernel/yap_kernel/interactiveshell.py index 1899e8232..751c0e933 100644 --- a/packages/python/yap_kernel/yap_kernel/interactiveshell.py +++ b/packages/python/yap_kernel/yap_kernel/interactiveshell.py @@ -1,14 +1,14 @@ # -*- coding: utf-8 -*- """YAP Stuff for Main IPython class.""" -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Copyright (C) 2001 Janko Hauser # Copyright (C) 2001-2007 Fernando Perez. # Copyright (C) 2008-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- from __future__ import absolute_import, print_function @@ -92,7 +92,7 @@ use_module = namedtuple('use_module', 'file') bindvars = namedtuple('bindvars', 'list') library = namedtuple('library', 'list') v = namedtuple('_', 'slot') -load_fieos = namedtuple('load_files', 'file ofile args') +load_files = namedtuple('load_files', 'file ofile args') class YAPInteraction: @@ -129,6 +129,8 @@ class YAPInteraction: def numbervars(self, l): return self.yapeng.fun(bindvars(l)) + + def run_cell(self, s, store_history=True, silent=False, shell_futures=True): """Run a complete IPython cell. @@ -148,8 +150,9 @@ class YAPInteraction: and logging. silent=True forces store_history=False. shell_futures : bool If True, the code will share future statements with the interactive - shell. It will both be affected by previous __future__ imports, and - any __future__ imports in the code will affect the shell. If False, + shell. It will both be affected by previous + __future__ imports, and any __future__ imports in the code + will affect the shell. If False, __future__ imports are not shared in either direction. Returns @@ -158,9 +161,7 @@ class YAPInteraction: """ result = ExecutionResult() - - if store_history: - result.execution_count = self.shell.execution_count + result.execution_count = self.shell.execution_count def error_before_exec(value): result.error_before_exec = value @@ -168,32 +169,28 @@ class YAPInteraction: return result # inspect for ?? in the text - st = s.strip('\n\j\r\t ') - if (st): - (p0, pm, pf) = st.rpartition('??') - if pm == '??': - if pf.isdigit(p): - maxits = int(pf)*2 - s = p0 - elif pf.isspace(p): - maxits = 1 - s = p0 - else: - s = st - maxits = 2 - else: - # business as usual - s = st - maxits = 2 - elif st == '': - # next. please - maxis = 2 - self.qclose() + # print(st) + # + maxits = 2 + s = s.strip('\n\j\r\t ') + if not self.q or s: + (self.q,out) = self.top_level(s, out) + else: + out = q.next_answer() + if self.q: + st = s.strip('\n\j\r\t ') + if st and st == '*': + maxits = 1 + elif st and st.isdigit(): + maxits = int(st)*2 + elif st and st != ';': + self.closeq() if not self.q: try: if s: - self.q = self.yapeng.query(s) + self.q = self.yapeng.query(ya[q.__hash__]) + self.vs = self.q.namedVarsVector() else: return except SyntaxError: @@ -204,37 +201,11 @@ class YAPInteraction: # if not silent: # self.shell..logger.log(cell, s) has_raised = False - self.run = True try: - while self.run and maxits != 0: - # f = io.StringIO() - # with redirect_stdout(f): - self.run = self.q.next() - # print('{0}'.format(f.getvalue())) - # Execute the user code - if self.run: - myvs = self.numbervars(self.q.namedVars()) - if myvs: - for eq in myvs: - name = eq[0] - binding = eq[1] - if name != binding: - print(name + " = " + str(binding)) - else: - print("yes") - if self.q.deterministic(): - self.closeq() - self.run = False - self.q = None - else: - maxits -= 2 - else: - print("No (more) answers") - self.closeq() - self.run = False + while (maxits != 0): + self.do_loop(maxits, gs) except Exception: result.error_in_exec = sys.exc_info()[1] - # self.showtraceback() has_raised = True self.closeq() @@ -244,8 +215,8 @@ class YAPInteraction: # ExecutionResult # self.displayhook.exec_result = None - self.events.trigger('post_execute') - if not silent: - self.events.trigger('post_self.run_cell') + # self.events.trigger('post_execute') + # if not silent: + # self.events.trigger('post_self.run_cell') return result diff --git a/packages/python/yap_kernel/yap_kernel/yapkernel.py b/packages/python/yap_kernel/yap_kernel/yapkernel.py index e1d677c03..344f133e2 100644 --- a/packages/python/yap_kernel/yap_kernel/yapkernel.py +++ b/packages/python/yap_kernel/yap_kernel/yapkernel.py @@ -57,6 +57,7 @@ class YAPKernel(KernelBase): self.shell_handlers[msg_type] = getattr(self.comm_manager, msg_type) self.engine = YAPInteraction(self) + self.shell._last_traceback = None self.shell.run_cell = self.engine.run_cell help_links = List([ diff --git a/pl/absf.yap b/pl/absf.yap index 3c2332844..e56cb6bef 100755 --- a/pl/absf.yap +++ b/pl/absf.yap @@ -267,12 +267,12 @@ absolute_file_name(File0,File) :- '$dir', { '$absf_trace'(' ~w next', [P0]) }, '$cat_file_name'(P0, E). -'$file_name'(Name, Opts, E) --> +'$file_name'(Name, _Opts, E) --> '$cat_file_name'(Name, E ). /* ( { - get_abs_file_parameter( file_type, Opts, Lib ), + get_abs_file_parameter( file_type, _Opts, Lib ), nonvar(Lib) } ->