Merge branch 'master' of github.com:vscosta/yap-6.3

This commit is contained in:
Vitor Santos Costa 2018-10-16 14:34:15 +01:00
commit 868961ebb5
43 changed files with 1932 additions and 1783 deletions

View File

@ -427,6 +427,8 @@ ructions *
Op(deallocate, p); Op(deallocate, p);
CACHE_Y_AS_ENV(YREG); CACHE_Y_AS_ENV(YREG);
// do this before checking
SREG = YREG;
check_trail(TR); check_trail(TR);
#ifndef NO_CHECKING #ifndef NO_CHECKING
/* check stacks */ /* check stacks */
@ -435,7 +437,6 @@ ructions *
PREG = NEXTOP(PREG, p); PREG = NEXTOP(PREG, p);
/* other instructions do depend on S being set by deallocate /* other instructions do depend on S being set by deallocate
:-( */ :-( */
SREG = YREG;
CPREG = (yamop *) ENV_YREG[E_CP]; CPREG = (yamop *) ENV_YREG[E_CP];
ENV = ENV_YREG = (CELL *) ENV_YREG[E_E]; ENV = ENV_YREG = (CELL *) ENV_YREG[E_E];
#ifdef DEPTH_LIMIT #ifdef DEPTH_LIMIT

158
C/dbase.c
View File

@ -25,92 +25,88 @@ static char SccsId[] = "%W% %G%";
* *
* @brief record and other forms of storing terms. * @brief record and other forms of storing terms.
* *
* @namespace prolog * /
/** @defgroup Internal_Database Internal Data Base
*
* @ingroup builtins
* @{
*
* Some programs need global information for, e.g. counting or collecting
* data obtained by backtracking. As a rule, to keep this information, the
* internal data base should be used instead of asserting and retracting
* clauses (as most novice programmers do), .
* In YAP (as in some other Prolog systems) the internal data base (i.d.b.
* for short) is faster, needs less space and provides a better insulation of
* program and data than using asserted/retracted clauses.
* The i.d.b. is implemented as a set of terms, accessed by keys that
* unlikely what happens in (non-Prolog) data bases are not part of the
* term. Under each key a list of terms is kept. References are provided so that
* terms can be identified: each term in the i.d.b. has a unique reference
* (references are also available for clauses of dynamic predicates).
*
* There is a strong analogy between the i.d.b. and the way dynamic
* predicates are stored. In fact, the main i.d.b. predicates might be
* implemented using dynamic predicates:
*
* ~~~~~
* recorda(X,T,R) :- asserta(idb(X,T),R).
* recordz(X,T,R) :- assertz(idb(X,T),R).
* recorded(X,T,R) :- clause(idb(X,T),R).
* ~~~~~
* We can take advantage of this, the other way around, as it is quite
* easy to write a simple Prolog interpreter, using the i.d.b.:
*
* ~~~~~
* asserta(G) :- recorda(interpreter,G,_).
* assertz(G) :- recordz(interpreter,G,_).
* retract(G) :- recorded(interpreter,G,R), !, erase(R).
* call(V) :- var(V), !, fail.
* call((H :- B)) :- !, recorded(interpreter,(H :- B),_), call(B).
* call(G) :- recorded(interpreter,G,_).
* ~~~~~
* In YAP, much attention has been given to the implementation of the
* i.d.b., especially to the problem of accelerating the access to terms kept in
* a large list under the same key. Besides using the key, YAP uses an internal
* lookup function, transparent to the user, to find only the terms that might
* unify. For instance, in a data base containing the terms
*
* ~~~~~
* b
* b(a)
* c(d)
* e(g)
* b(X)
* e(h)
* ~~~~~
*
* stored under the key k/1, when executing the query
*
* ~~~~~
* :- recorded(k(_),c(_),R).
* ~~~~~
*
* `recorded` would proceed directly to the third term, spending almost the
* time as if `a(X)` or `b(X)` was being searched.
* The lookup function uses the functor of the term, and its first three
* arguments (when they exist). So, `recorded(k(_),e(h),_)` would go
* directly to the last term, while `recorded(k(_),e(_),_)` would find
* first the fourth term, and then, after backtracking, the last one.
*
* This mechanism may be useful to implement a sort of hierarchy, where
* the functors of the terms (and eventually the first arguments) work as
* secondary keys.
*
* In the YAP's i.d.b. an optimized representation is used for
* terms without free variables. This results in a faster retrieval of terms
* and better space usage. Whenever possible, avoid variables in terms in terms
* stored in the i.d.b.
* *
* *
* *
*/ */
/** @defgroup Internal_Database Internal Data Base
@ingroup builtins
@{
Some programs need global information for, e.g. counting or collecting
data obtained by backtracking. As a rule, to keep this information, the
internal data base should be used instead of asserting and retracting
clauses (as most novice programmers do), .
In YAP (as in some other Prolog systems) the internal data base (i.d.b.
for short) is faster, needs less space and provides a better insulation of
program and data than using asserted/retracted clauses.
The i.d.b. is implemented as a set of terms, accessed by keys that
unlikely what happens in (non-Prolog) data bases are not part of the
term. Under each key a list of terms is kept. References are provided so that
terms can be identified: each term in the i.d.b. has a unique reference
(references are also available for clauses of dynamic predicates).
There is a strong analogy between the i.d.b. and the way dynamic
predicates are stored. In fact, the main i.d.b. predicates might be
implemented using dynamic predicates:
~~~~~
recorda(X,T,R) :- asserta(idb(X,T),R).
recordz(X,T,R) :- assertz(idb(X,T),R).
recorded(X,T,R) :- clause(idb(X,T),R).
~~~~~
We can take advantage of this, the other way around, as it is quite
easy to write a simple Prolog interpreter, using the i.d.b.:
~~~~~
asserta(G) :- recorda(interpreter,G,_).
assertz(G) :- recordz(interpreter,G,_).
retract(G) :- recorded(interpreter,G,R), !, erase(R).
call(V) :- var(V), !, fail.
call((H :- B)) :- !, recorded(interpreter,(H :- B),_), call(B).
call(G) :- recorded(interpreter,G,_).
~~~~~
In YAP, much attention has been given to the implementation of the
i.d.b., especially to the problem of accelerating the access to terms kept in
a large list under the same key. Besides using the key, YAP uses an internal
lookup function, transparent to the user, to find only the terms that might
unify. For instance, in a data base containing the terms
~~~~~
b
b(a)
c(d)
e(g)
b(X)
e(h)
~~~~~
stored under the key k/1, when executing the query
~~~~~
:- recorded(k(_),c(_),R).
~~~~~
`recorded` would proceed directly to the third term, spending almost the
time as if `a(X)` or `b(X)` was being searched.
The lookup function uses the functor of the term, and its first three
arguments (when they exist). So, `recorded(k(_),e(h),_)` would go
directly to the last term, while `recorded(k(_),e(_),_)` would find
first the fourth term, and then, after backtracking, the last one.
This mechanism may be useful to implement a sort of hierarchy, where
the functors of the terms (and eventually the first arguments) work as
secondary keys.
In the YAP's i.d.b. an optimized representation is used for
terms without free variables. This results in a faster retrieval of terms
and better space usage. Whenever possible, avoid variables in terms in terms
stored in the i.d.b.
*/
#include "Yap.h" #include "Yap.h"
#include "attvar.h" #include "attvar.h"
#include "clause.h" #include "clause.h"

View File

@ -90,8 +90,8 @@ endforeach(i ${DOCS_EXCLUDE_})
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_ SET(DOC_INPUT_FILES_
${CMAKE_SOURCE_DIR}/pl
${CMAKE_SOURCE_DIR}/docs/md ${CMAKE_SOURCE_DIR}/docs/md
${CMAKE_SOURCE_DIR}/pl
${CMAKE_SOURCE_DIR}/CXX ${CMAKE_SOURCE_DIR}/CXX
${CMAKE_SOURCE_DIR}/OPTYap ${CMAKE_SOURCE_DIR}/OPTYap
${CMAKE_SOURCE_DIR}/C ${CMAKE_SOURCE_DIR}/C

View File

@ -20,4 +20,6 @@ notation will be used:
+ an argument with no preceding symbol can be used in both ways. + an argument with no preceding symbol can be used in both ways.
@{ [TOC]
@}

View File

@ -127,8 +127,8 @@ The rest of this appendix describes exhaustively how to interface C to YAP.
@} @}
@defgroup Manipulating_Terms Terms @defgroup Manipulating_Terms Terms
@{
@ingroup ChYInterface @ingroup ChYInterface
@{
This section provides information about the primitives available to the C This section provides information about the primitives available to the C
programmer for manipulating Prolog terms. programmer for manipulating Prolog terms.
@ -504,8 +504,8 @@ code. Slots can also be used if there is small state.
@} @}
@defgroup Unifying_Terms Unification @defgroup Unifying_Terms Unification
@{
@ingroup ChYInterface @ingroup ChYInterface
@{
YAP provides a single routine to attempt the unification of two Prolog YAP provides a single routine to attempt the unification of two Prolog
terms. The routine may succeed or fail: terms. The routine may succeed or fail:
@ -522,8 +522,8 @@ otherwise.
@} @}
@defgroup CallYAP Using the compiler: @defgroup CallYAP Using the compiler:
@{
@ingroup Manipulating_Strings Strings @ingroup Manipulating_Strings Strings
@{
The YAP C-interface now includes an utility routine to copy a string The YAP C-interface now includes an utility routine to copy a string
@ -608,8 +608,8 @@ and <tt>-1</tt> on error.
@} @}
@defgroup Memory_Allocation Memory Allocation @defgroup Memory_Allocation Memory Allocation
@{
@ingroup ChYInterface @ingroup ChYInterface
@{
The next routine can be used to ask space from the Prolog data-base: The next routine can be used to ask space from the Prolog data-base:
@ -638,8 +638,8 @@ area.
@} @}
@defgroup Controlling_Streams Controlling YAP Streams from `C` @defgroup Controlling_Streams Controlling YAP Streams from `C`
@{
@ingroup ChYInterface @ingroup ChYInterface
@{
The C-Interface also provides the C-application with a measure of The C-Interface also provides the C-application with a measure of
control over the YAP Input/Output system. The first routine allows one control over the YAP Input/Output system. The first routine allows one
@ -698,8 +698,8 @@ the name by which YAP should know the new stream.
@} @}
@defgroup Utility_Functions Utility Functions in `C @defgroup Utility_Functions Utility Functions in `C
@{
@ingroup ChYInterface @ingroup ChYInterface
@{
The C-Interface provides the C-application with a a number of utility The C-Interface provides the C-application with a a number of utility
functions that are useful. functions that are useful.
@ -794,9 +794,8 @@ ignore the variable.
@} @}
@defgroup Calling_YAP_From_C From `C` back to Prolog @defgroup Calling_YAP_From_C From `C` back to Prolog
@{
@ingroup ChYInterface @ingroup ChYInterface
### From `C` back to Prolog {#Calling_YAP_From_C} @{
There are several ways to call Prolog code from C-code. By default, the There are several ways to call Prolog code from C-code. By default, the
`YAP_RunGoal()` should be used for this task. It assumes the engine `YAP_RunGoal()` should be used for this task. It assumes the engine
@ -967,8 +966,8 @@ have moved the terms
@} @}
@defgroup CallYAP Using the compiler: @defgroup CallYAP Using the compiler:
@{
@ingroup Module_Manipulation_in_C Module Manipulation in C @ingroup Module_Manipulation_in_C Module Manipulation in C
@{
YAP allows one to create a new module from C-code. To create the new YAP allows one to create a new module from C-code. To create the new
code it is sufficient to call: code it is sufficient to call:
@ -998,8 +997,8 @@ Notice that this function returns a term, and not an atom. You can
@} @}
@defgroup Miscellaneous_ChYFunctions Miscellaneous C Functions @defgroup Miscellaneous_ChYFunctions Miscellaneous C Functions
@{
@ingroup ChYInterface @ingroup ChYInterface
@{
<ul> <ul>
<li>`void` YAP_Throw(`YAP_Term exception`) <li>`void` YAP_Throw(`YAP_Term exception`)
@ -1064,9 +1063,8 @@ of such arguments.
@} @}
@defgroup Writing_C Writing predicates in C @defgroup Writing_C Writing predicates in C
@{
@ingroup ChYInterface @ingroup ChYInterface
### Writing predicates in C {#Writing_C} @{
We will distinguish two kinds of predicates: We will distinguish two kinds of predicates:
@ -1321,8 +1319,8 @@ in this case no code is executed at cut time.
@} @}
@defgroup YAP4_Notes Changes to the C-Interface in YAP4 @defgroup YAP4_Notes Changes to the C-Interface in YAP4
@{
@ingroup ChYInterface @ingroup ChYInterface
@{
YAP4 includes several changes over the previous `load_foreign_files/3` YAP4 includes several changes over the previous `load_foreign_files/3`
interface. These changes were required to support the new binary code interface. These changes were required to support the new binary code
@ -1361,8 +1359,8 @@ arguments to the backtrackable procedure.
@} @}
@defgroup YAPAsLibrary Using YAP as a Library @defgroup YAPAsLibrary Using YAP as a Library
@{
@ingroup ChYInterface @ingroup ChYInterface
@{
YAP can be used as a library to be called from other YAP can be used as a library to be called from other
programs. To do so, you must first create the YAP library: programs. To do so, you must first create the YAP library:

View File

@ -6,4 +6,6 @@
`LIBDIR` variable in the Makefile for YAP). Several files in the `LIBDIR` variable in the Makefile for YAP). Several files in the
library are originally from the public-domain Edinburgh Prolog library. library are originally from the public-domain Edinburgh Prolog library.
[TOC]
@} @}

View File

@ -141,7 +141,7 @@ We present the main predicates and directives available to load
their public predicates into the current type-in module. It is their public predicates into the current type-in module. It is
implemented as if by: implemented as if by:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.prolog} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.yap}
use_module(F) :- use_module(F) :-
load_files(F, [if(not_loaded),must_be_module(true)]). load_files(F, [if(not_loaded),must_be_module(true)]).
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -775,6 +775,9 @@ rhs(log(RHS), Logs ) :- !,
rhs(exp(RHS), Logs ) :- !, rhs(exp(RHS), Logs ) :- !,
rhs(RHS, X1), rhs(RHS, X1),
matrix_to_exps( X1, Logs ). matrix_to_exps( X1, Logs ).
rhs(sum(RHS), Logs ) :- !,
rhs(RHS, X1),
matrix_sum( X1, Logs ).
rhs(S, NS) :- rhs(S, NS) :-
rhs_opaque( S ), !, rhs_opaque( S ), !,
S = NS. S = NS.

View File

@ -788,15 +788,17 @@ path.
The predicates performs a left-recursive traversal. It does not protect against file system errors and it does not check for symbolic links. The predicates performs a left-recursive traversal. It does not protect against file system errors and it does not check for symbolic links.
*/ */
directory_map(D, P), directory_map(D, P) :-
working_directory(_, D), working_directory(_, D),
list_directory(D,L), list_directory(D,L),
d_map(L, P). d_map(L, P).
d_map([],_,_,_). d_map([],_,_,_).
d_map(['.'|Fs],D, P) :- d_map(['.'|Fs],D, P) :-
!,
d_map(Fs,D, P). d_map(Fs,D, P).
d_map(['..'|Fs],D, P) :- d_map(['..'|Fs],D, P) :-
!,
d_map(Fs, D, P). d_map(Fs, D, P).
d_map([D|Fs], D, P) :- d_map([D|Fs], D, P) :-
absolute_file_name( F, File, [prefix(D)] ), absolute_file_name( F, File, [prefix(D)] ),

File diff suppressed because it is too large Load Diff

View File

@ -832,10 +832,7 @@ gradient_descent :-
forall(tunable_fact(FactID,GroundTruth), forall(tunable_fact(FactID,GroundTruth),
(XZ is 0.0, X[FactID] <== XZ,sigmoid(XZ,Slope,Pr),set_fact_probability(FactID,Pr))), (XZ is 0.0, X[FactID] <== XZ,sigmoid(XZ,Slope,Pr),set_fact_probability(FactID,Pr))),
problog_flag(sigmoid_slope,Slope), problog_flag(sigmoid_slope,Slope),
lbfgs_run(Solver,BestF), lbfgs_run(Solver,_BestF),
format('~2nOptimization done~nWe found a minimum ~4f.~n',[BestF]),
forall(tunable_fact(FactID,GroundTruth), set_tunable(FactID,Slope,X)),
set_problog_flag(mse_trainset, BestF),
lbfgs_finalize(Solver). lbfgs_finalize(Solver).
set_tunable(I,Slope,P) :- set_tunable(I,Slope,P) :-
@ -848,38 +845,42 @@ set_tunable(I,Slope,P) :-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
user:evaluate(LLH_Training_Queries, X,Grad,N,_,_) :- user:evaluate(LLH_Training_Queries, X,Grad,N,_,_) :-
%Handle = user_error, %Handle = user_error,
GradCount <== array[N] of ints, example_count(TrainingExampleCount),
LLs <== array[TrainingExampleCount ] of floats,
Probs <== array[N] of floats, Probs <== array[N] of floats,
problog_flag(sigmoid_slope,Slope), problog_flag(sigmoid_slope,Slope),
N1 is N-1, N1 is N-1,
forall(between(0,N1,I), forall(between(0,N1,I),
(Grad[I] <== 0.0, S <== X[I], sigmoid(S,Slope, P), Probs[I] <== P) (Grad[I] <== 0.0, S <== X[I], sigmoid(S,Slope, P), Probs[I] <== P)
), ), nl,
findall(LL, forall(
compute_grad(Grad, GradCount, Probs, Slope, LL), full_example(QueryID,QueryProb,BDD),
LLs compute_grad(QueryID, BDD, QueryProb,Grad, Probs, Slope,LLs)
), ),
sum_list(LLs,LLH_Training_Queries). LLH_Training_Queries <== sum(LLs),
writeln(LLH_Training_Queries).
%wrap(X, Grad, GradCount). %wrap(X, Grad, GradCount).
full_example(QueryID,QueryProb,BDD) :-
user:example(QueryID,_Query,QueryProb,_),
recorded(QueryID,BDD,_),
BDD = bdd(_Dir, _GradTree, MapList),
MapList = [_|_].
compute_grad(Grad, GradCount, Probs, Slope, LL) :- compute_grad(QueryID,BDD,QueryProb, Grad, Probs, Slope, LLs) :-
user:example(QueryID,_Query,QueryProb,_), BDD = bdd(_Dir, _GradTree, MapList),
recorded(QueryID,BDD,_), bind_maplist(MapList, Slope, Probs),
BDD = bdd(_Dir, _GradTree, MapList), recorded(QueryID,BDD,_),
MapList = [_|_],
bind_maplist(MapList, Slope, Probs),
%writeln( MapList ),
qprobability(BDD,Slope,BDDProb), qprobability(BDD,Slope,BDDProb),
LL is (BDDProb-QueryProb)*(BDDProb-QueryProb), LL is (BDDProb-QueryProb)*(BDDProb-QueryProb),
LLs[QueryID] <== LL,
%writeln( qprobability(BDD,Slope,BDDProb) ), %writeln( qprobability(BDD,Slope,BDDProb) ),
forall( forall(
member(I-_, MapList), member(I-_, MapList),
gradientpair(I, BDD,Slope,BDDProb, QueryProb, Grad, Probs, GradCount) gradientpair(I, BDD,Slope,BDDProb, QueryProb, Grad, Probs)
). ).
gradientpair(I, BDD,Slope,BDDProb, QueryProb, Grad, Probs, GradCount) :- gradientpair(I, BDD,Slope,BDDProb, QueryProb, Grad, Probs) :-
qgradient(I, BDD, Slope, FactID, GradValue), qgradient(I, BDD, Slope, FactID, GradValue),
% writeln(FactID), % writeln(FactID),
G0 <== Grad[FactID], G0 <== Grad[FactID],
@ -887,10 +888,7 @@ gradientpair(I, BDD,Slope,BDDProb, QueryProb, Grad, Probs, GradCount) :-
%writeln( GN is G0-GradValue*(QueryProb-BDDProb)), %writeln( GN is G0-GradValue*(QueryProb-BDDProb)),
GN is G0-GradValue*2*Prob*(1-Prob)*(QueryProb-BDDProb), GN is G0-GradValue*2*Prob*(1-Prob)*(QueryProb-BDDProb),
%writeln(FactID:(G0->GN)), %writeln(FactID:(G0->GN)),
GC <== GradCount[FactID], Grad[FactID] <== GN.
GC1 is GC+1,
GradCount[FactID] <== GC1,
Grad[FactID] <== GN.
qprobability(bdd(Dir, Tree, _MapList), Slope, Prob) :- qprobability(bdd(Dir, Tree, _MapList), Slope, Prob) :-
/* query_probability(21,6.775948e-01). */ /* query_probability(21,6.775948e-01). */
@ -980,6 +978,13 @@ bind_maplist([Node-Pr|MapList], Slope, X) :-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
user:progress(FX,X,_G,X_Norm,G_Norm,Step,_N,Iteration,Ls,0) :- user:progress(FX,X,_G,X_Norm,G_Norm,Step,_N,Iteration,Ls,0) :-
problog_flag(sigmoid_slope,Slope), problog_flag(sigmoid_slope,Slope),
forall(tunable_fact(FactID,_GroundTruth), set_tunable(FactID,Slope,X)),
current_iteration(CurrentIteration),
retractall(current_iteration(_)),
NextIteration is CurrentIteration+1,
assertz(current_iteration(NextIteration)),
save_model,
set_problog_flag(mse_trainset, FX),
X0 <== X[0], sigmoid(X0,Slope,P0), X0 <== X[0], sigmoid(X0,Slope,P0),
X1 <== X[1], sigmoid(X1,Slope,P1), X1 <== X[1], sigmoid(X1,Slope,P1),
format('~d. Iteration : (x0,x1)=(~4f,~4f) f(X)=~4f |X|=~4f |X\'|=~4f Step=~4f Ls=~4f~n',[Iteration,P0 ,P1,FX,X_Norm,G_Norm,Step,Ls]). format('~d. Iteration : (x0,x1)=(~4f,~4f) f(X)=~4f |X|=~4f |X\'|=~4f Step=~4f Ls=~4f~n',[Iteration,P0 ,P1,FX,X_Norm,G_Norm,Step,Ls]).

View File

@ -1,4 +1,4 @@
set (PYTHON_SOURCES backcall/__init__.py set (PYTHON_SOURCES
core/yap_kernel/__init__.py core/yap_kernel/__init__.py
core/yap_kernel/getipython.py core/yap_kernel/getipython.py
core/__init__.py core/__init__.py
@ -65,7 +65,6 @@ kernelspec.py
__init__.py __init__.py
yap_kernel_launcher.py yap_kernel_launcher.py
docs/conf.py docs/conf.py
backcall.py
setup.py setup.py
interactiveshell.py interactiveshell.py
examples/embedding/internal_ipkernel.py examples/embedding/internal_ipkernel.py
@ -154,7 +153,6 @@ yap_ipython/core/logger.py
yap_ipython/core/excolors.py yap_ipython/core/excolors.py
yap_ipython/core/completer.py yap_ipython/core/completer.py
yap_ipython/core/ultratb.py yap_ipython/core/ultratb.py
yap_ipython/core/backcall.py
yap_ipython/core/display.py yap_ipython/core/display.py
yap_ipython/core/prompts.py yap_ipython/core/prompts.py
yap_ipython/core/debugger.py yap_ipython/core/debugger.py

View File

@ -41,7 +41,7 @@ jupyter_cell(Caller, _, Line ) :-
Query = Caller, Query = Caller,
catch( catch(
python_query(Query,Line), python_query(Query,Line),
E=error(A,B), error(A,B),
system_error(A,B) system_error(A,B)
). ).
@ -69,7 +69,7 @@ jupyter_consult(Cell) :-
open_mem_read_stream( Cell, Stream), open_mem_read_stream( Cell, Stream),
load_files(user:'jupyter cell',[stream(Stream)| Options]) load_files(user:'jupyter cell',[stream(Stream)| Options])
), ),
E=error(A,B), error(A,B),
(close(Stream), system_error(A,B)) (close(Stream), system_error(A,B))
), ),
fail. fail.

View File

@ -23,7 +23,7 @@
jupyter( []). jupyter( []).
ready( Engine, Query) :- ready( Engine, Query) :-
errors( Engine , Cell ), errors( Engine , Query ),
Es := Engine.errors, Es := Engine.errors,
not Es == []. not Es == [].
@ -50,11 +50,11 @@ open_esh(Engine , Text, Stream, Name) :-
Name := Engine.stream_name, Name := Engine.stream_name,
open_mem_read_stream( Text, Stream ). open_mem_read_stream( Text, Stream ).
esh(Engine , Name, Stream) :- esh(Engine , _Name, Stream) :-
repeat, repeat,
catch( catch(
read_clause(Stream, Cl, [ syntax_errors(dec10)]), read_clause(Stream, Cl, [ syntax_errors(dec10)]),
error(C,E), error(C,E),
p3_message(C,Engine,E) p3_message(C,Engine,E)
), ),
Cl == end_of_file, Cl == end_of_file,
@ -77,19 +77,19 @@ close_esh( _Engine , Stream ) :-
p3_message( _Severity, Engine, error(syntax_error(Cause),info(between(_,LN,_), _FileName, CharPos, Details))) :- p3_message( _Severity, Engine, error(syntax_error(Cause),info(between(_,LN,_), _FileName, CharPos, Details))) :-
python_clear_errors, python_clear_errors,
!, !,
Engine.errors := [t(Cause,LN,CharPos,Details)]+Engine.errors. Engine.errors := [t(Cause,LN,CharPos,Details)]+Engine.errors .
p3_message(error, Engine, E) :- p3_message(error, _Engine, _E) :-
python_clear_errors, python_clear_errors,
!. !.
p3_message(warning, Engine, E) :- p3_message(warning, _Engine, _E) :-
!. !.
p3_message(error, Engine, E) :- p3_message(error, Engine, E) :-
Engine.errors := [E] + Engine.errors. Engine.errors := [E] + Engine.errors.
p3_message(warning, Engine, E) :- p3_message(warning, Engine, E) :-
Engine.errors := [E] + Engine.errors. Engine.errors := [E] + Engine.errors.
%% ready(_Self, Line ) :- %% ready(_Self, Line ) :-
%% blank( Line ), %% blank( Line ),
%% !. %% !.
%% ready(Self, Line ) :- %% ready(Self, Line ) :-

View File

@ -3,20 +3,19 @@ import sys
from yap_ipython.core.debugger import Pdb from yap_ipython.core.debugger import Pdb
from yap_ipython.yapi import YAPCompleter from yap_ipython.core.completer import IPCompleter
#from .ptutils import IPythonPTCompleter from .ptutils import IPythonPTCompleter
from .shortcuts import suspend_to_bg, cursor_in_leading_ws from .shortcuts import suspend_to_bg, cursor_in_leading_ws
from prompt_toolkit.enums import DEFAULT_BUFFER from prompt_toolkit.enums import DEFAULT_BUFFER
from prompt_toolkit.filters import (Condition, HasFocus, HasSelection, from prompt_toolkit.filters import (Condition, has_focus, has_selection,
ViInsertMode, EmacsInsertMode) vi_insert_mode, emacs_insert_mode)
from prompt_toolkit.keys import Keys from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit.key_binding.manager import KeyBindingManager
from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline
from prompt_toolkit.token import Token from pygments.token import Token
from prompt_toolkit.shortcuts import create_prompt_application from prompt_toolkit.shortcuts.prompt import PromptSession
from prompt_toolkit.interface import CommandLineInterface
from prompt_toolkit.enums import EditingMode from prompt_toolkit.enums import EditingMode
from prompt_toolkit.formatted_text import PygmentsTokens
class TerminalPdb(Pdb): class TerminalPdb(Pdb):
@ -26,46 +25,40 @@ class TerminalPdb(Pdb):
self.pt_init() self.pt_init()
def pt_init(self): def pt_init(self):
def get_prompt_tokens(cli): def get_prompt_tokens():
return [(Token.Prompt, self.prompt)] return [(Token.Prompt, self.prompt)]
def patch_stdout(**kwargs):
return self.pt_cli.patch_stdout_context(**kwargs)
if self._ptcomp is None: if self._ptcomp is None:
compl = IPCompleter(shell=self.shell, compl = IPCompleter(shell=self.shell,
namespace={}, namespace={},
global_namespace={}, global_namespace={},
parent=self.shell, parent=self.shell,
) )
self._ptcomp = IPythonPTCompleter(compl, patch_stdout=patch_stdout) self._ptcomp = IPythonPTCompleter(compl)
kbmanager = KeyBindingManager.for_prompt() kb = KeyBindings()
supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP')) supports_suspend = Condition(lambda: hasattr(signal, 'SIGTSTP'))
kbmanager.registry.add_binding(Keys.ControlZ, filter=supports_suspend kb.add('c-z', filter=supports_suspend)(suspend_to_bg)
)(suspend_to_bg)
if self.shell.display_completions == 'readlinelike': if self.shell.display_completions == 'readlinelike':
kbmanager.registry.add_binding(Keys.ControlI, kb.add('tab', filter=(has_focus(DEFAULT_BUFFER)
filter=(HasFocus(DEFAULT_BUFFER) & ~has_selection
& ~HasSelection() & vi_insert_mode | emacs_insert_mode
& ViInsertMode() | EmacsInsertMode() & ~cursor_in_leading_ws
& ~cursor_in_leading_ws ))(display_completions_like_readline)
))(display_completions_like_readline)
multicolumn = (self.shell.display_completions == 'multicolumn')
self._pt_app = create_prompt_application( self.pt_app = PromptSession(
message=(lambda: PygmentsTokens(get_prompt_tokens())),
editing_mode=getattr(EditingMode, self.shell.editing_mode.upper()), editing_mode=getattr(EditingMode, self.shell.editing_mode.upper()),
key_bindings_registry=kbmanager.registry, key_bindings=kb,
history=self.shell.debugger_history, history=self.shell.debugger_history,
completer= self._ptcomp, completer=self._ptcomp,
enable_history_search=True, enable_history_search=True,
mouse_support=self.shell.mouse_support, mouse_support=self.shell.mouse_support,
get_prompt_tokens=get_prompt_tokens, complete_style=self.shell.pt_complete_style,
display_completions_in_columns=multicolumn, style=self.shell.style,
style=self.shell.style inputhook=self.shell.inputhook,
) )
self.pt_cli = CommandLineInterface(self._pt_app, eventloop=self.shell._eventloop)
def cmdloop(self, intro=None): def cmdloop(self, intro=None):
"""Repeatedly issue a prompt, accept input, parse an initial prefix """Repeatedly issue a prompt, accept input, parse an initial prefix
@ -92,7 +85,7 @@ class TerminalPdb(Pdb):
self._ptcomp.ipy_completer.namespace = self.curframe_locals self._ptcomp.ipy_completer.namespace = self.curframe_locals
self._ptcomp.ipy_completer.global_namespace = self.curframe.f_globals self._ptcomp.ipy_completer.global_namespace = self.curframe.f_globals
try: try:
line = self.pt_cli.run(reset_current_buffer=True).text line = self.pt_app.prompt() # reset_current_buffer=True)
except EOFError: except EOFError:
line = 'EOF' line = 'EOF'
line = self.precmd(line) line = self.precmd(line)

View File

@ -366,6 +366,9 @@ def embed(**kwargs):
config = load_default_config() config = load_default_config()
config.InteractiveShellEmbed = config.TerminalInteractiveShell config.InteractiveShellEmbed = config.TerminalInteractiveShell
kwargs['config'] = config kwargs['config'] = config
using = kwargs.get('using', 'sync')
if using :
kwargs['config'].update({'TerminalInteractiveShell':{'loop_runner':using, 'colors':'NoColor', 'autoawait': using!='sync'}})
#save ps1/ps2 if defined #save ps1/ps2 if defined
ps1 = None ps1 = None
ps2 = None ps2 = None
@ -383,7 +386,7 @@ def embed(**kwargs):
shell = InteractiveShellEmbed.instance(_init_location_id='%s:%s' % ( shell = InteractiveShellEmbed.instance(_init_location_id='%s:%s' % (
frame.f_code.co_filename, frame.f_lineno), **kwargs) frame.f_code.co_filename, frame.f_lineno), **kwargs)
shell(header=header, stack_depth=2, compile_flags=compile_flags, shell(header=header, stack_depth=2, compile_flags=compile_flags,
_call_location_id='%s:%s' % (frame.f_code.co_filename, frame.f_lineno)) _call_location_id='%s:%s' % (frame.f_code.co_filename, frame.f_lineno))
InteractiveShellEmbed.clear_instance() InteractiveShellEmbed.clear_instance()
#restore previous instance #restore previous instance
if saved_shell_instance is not None: if saved_shell_instance is not None:

View File

@ -12,18 +12,19 @@ from yap_ipython.utils.terminal import toggle_set_term_title, set_term_title
from yap_ipython.utils.process import abbrev_cwd from yap_ipython.utils.process import abbrev_cwd
from traitlets import ( from traitlets import (
Bool, Unicode, Dict, Integer, observe, Instance, Type, default, Enum, Union, Bool, Unicode, Dict, Integer, observe, Instance, Type, default, Enum, Union,
Any, Any, validate
) )
from prompt_toolkit.document import Document
from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode
from prompt_toolkit.filters import (HasFocus, Condition, IsDone) from prompt_toolkit.filters import (HasFocus, Condition, IsDone)
from prompt_toolkit.formatted_text import PygmentsTokens
from prompt_toolkit.history import InMemoryHistory from prompt_toolkit.history import InMemoryHistory
from prompt_toolkit.shortcuts import create_prompt_application, create_eventloop, create_prompt_layout, create_output
from prompt_toolkit.interface import CommandLineInterface
from prompt_toolkit.key_binding.manager import KeyBindingManager
from prompt_toolkit.layout.processors import ConditionalProcessor, HighlightMatchingBracketProcessor from prompt_toolkit.layout.processors import ConditionalProcessor, HighlightMatchingBracketProcessor
from prompt_toolkit.styles import PygmentsStyle, DynamicStyle from prompt_toolkit.output import ColorDepth
from prompt_toolkit.patch_stdout import patch_stdout
from prompt_toolkit.shortcuts import PromptSession, CompleteStyle, print_formatted_text
from prompt_toolkit.styles import DynamicStyle, merge_styles
from prompt_toolkit.styles.pygments import style_from_pygments_cls, style_from_pygments_dict
from pygments.styles import get_style_by_name from pygments.styles import get_style_by_name
from pygments.style import Style from pygments.style import Style
@ -33,8 +34,8 @@ from .debugger import TerminalPdb, Pdb
from .magics import TerminalMagics from .magics import TerminalMagics
from .pt_inputhooks import get_inputhook_name_and_func from .pt_inputhooks import get_inputhook_name_and_func
from .prompts import Prompts, ClassicPrompts, RichPromptDisplayHook from .prompts import Prompts, ClassicPrompts, RichPromptDisplayHook
#from .ptutils import IPythonPTCompleter, IPythonPTLexer from .ptutils import IPythonPTCompleter, IPythonPTLexer
from .shortcuts import register_ipython_shortcuts from .shortcuts import create_ipython_shortcuts
DISPLAY_BANNER_DEPRECATED = object() DISPLAY_BANNER_DEPRECATED = object()
@ -57,8 +58,6 @@ _style_overrides_linux = {
Token.OutPromptNum: '#bb0000 bold', Token.OutPromptNum: '#bb0000 bold',
} }
def get_default_editor(): def get_default_editor():
try: try:
return os.environ['EDITOR'] return os.environ['EDITOR']
@ -90,15 +89,11 @@ _use_simple_prompt = ('IPY_TEST_SIMPLE_PROMPT' in os.environ) or (not _is_tty)
class TerminalInteractiveShell(InteractiveShell): class TerminalInteractiveShell(InteractiveShell):
space_for_menu = Integer(6, help='Number of line at the bottom of the screen ' space_for_menu = Integer(6, help='Number of line at the bottom of the screen '
'to reserve for the completion menu' 'to reserve for the completion menu'
).tag(config=True) ).tag(config=True)
def _space_for_menu_changed(self, old, new): pt_app = None
self._update_layout()
pt_cli = None
debugger_history = None debugger_history = None
_pt_app = None
simple_prompt = Bool(_use_simple_prompt, simple_prompt = Bool(_use_simple_prompt,
help="""Use `raw_input` for the REPL, without completion and prompt colors. help="""Use `raw_input` for the REPL, without completion and prompt colors.
@ -136,6 +131,23 @@ class TerminalInteractiveShell(InteractiveShell):
highlighting. To see available styles, run `pygmentize -L styles`.""" highlighting. To see available styles, run `pygmentize -L styles`."""
).tag(config=True) ).tag(config=True)
@validate('editing_mode')
def _validate_editing_mode(self, proposal):
if proposal['value'].lower() == 'vim':
proposal['value']= 'vi'
elif proposal['value'].lower() == 'default':
proposal['value']= 'emacs'
if hasattr(EditingMode, proposal['value'].upper()):
return proposal['value'].lower()
return self.editing_mode
@observe('editing_mode')
def _editing_mode(self, change):
u_mode = change.new.upper()
self.pt_app.editing_mode = u_mode
@observe('highlighting_style') @observe('highlighting_style')
@observe('colors') @observe('colors')
@ -169,9 +181,9 @@ class TerminalInteractiveShell(InteractiveShell):
def _prompts_default(self): def _prompts_default(self):
return self.prompts_class(self) return self.prompts_class(self)
@observe('prompts') # @observe('prompts')
def _(self, change): # def _(self, change):
self._update_layout() # self._update_layout()
@default('displayhook_class') @default('displayhook_class')
def _displayhook_class_default(self): def _displayhook_class_default(self):
@ -208,6 +220,10 @@ class TerminalInteractiveShell(InteractiveShell):
"may be changed or removed in later releases." "may be changed or removed in later releases."
).tag(config=True) ).tag(config=True)
enable_history_search = Bool(True,
help="Allows to enable/disable the prompt toolkit history search"
).tag(config=True)
@observe('term_title') @observe('term_title')
def init_term_title(self, change=None): def init_term_title(self, change=None):
# Enable or disable the terminal title. # Enable or disable the terminal title.
@ -227,24 +243,19 @@ class TerminalInteractiveShell(InteractiveShell):
def init_prompt_toolkit_cli(self): def init_prompt_toolkit_cli(self):
if self.simple_prompt: if self.simple_prompt:
# Fall back to plain non-interactive output for tests. # Fall back to plain non-interactive output for tests.
# This is very limited, and only accepts a single line. # This is very limited.
def prompt(): def prompt():
isp = self.input_splitter
prompt_text = "".join(x[1] for x in self.prompts.in_prompt_tokens()) prompt_text = "".join(x[1] for x in self.prompts.in_prompt_tokens())
lines = [input(prompt_text)]
prompt_continuation = "".join(x[1] for x in self.prompts.continuation_prompt_tokens()) prompt_continuation = "".join(x[1] for x in self.prompts.continuation_prompt_tokens())
while isp.push_accepts_more(): while self.check_complete('\n'.join(lines))[0] == 'incomplete':
line = input(prompt_text) lines.append( input(prompt_continuation) )
isp.push(line) return '\n'.join(lines)
prompt_text = prompt_continuation
return isp.source_reset()
self.prompt_for_code = prompt self.prompt_for_code = prompt
return return
# Set up keyboard shortcuts # Set up keyboard shortcuts
kbmanager = KeyBindingManager.for_prompt( key_bindings = create_ipython_shortcuts(self)
enable_open_in_editor=self.extra_open_editor_shortcuts,
)
register_ipython_shortcuts(kbmanager.registry, self)
# Pre-populate history from yap_ipython's history database # Pre-populate history from yap_ipython's history database
history = InMemoryHistory() history = InMemoryHistory()
@ -254,7 +265,7 @@ class TerminalInteractiveShell(InteractiveShell):
# Ignore blank lines and consecutive duplicates # Ignore blank lines and consecutive duplicates
cell = cell.rstrip() cell = cell.rstrip()
if cell and (cell != last_cell): if cell and (cell != last_cell):
history.append(cell) history.append_string(cell)
last_cell = cell last_cell = cell
self._style = self._make_style_from_name_or_cls(self.highlighting_style) self._style = self._make_style_from_name_or_cls(self.highlighting_style)
@ -262,24 +273,18 @@ class TerminalInteractiveShell(InteractiveShell):
editing_mode = getattr(EditingMode, self.editing_mode.upper()) editing_mode = getattr(EditingMode, self.editing_mode.upper())
def patch_stdout(**kwargs): self.pt_app = PromptSession(
return self.pt_cli.patch_stdout_context(**kwargs)
self._pt_app = create_prompt_application(
editing_mode=editing_mode, editing_mode=editing_mode,
key_bindings_registry=kbmanager.registry, key_bindings=key_bindings,
history=history, history=history,
# completer=IPythonPTCompleter(shell=self, completer=IPythonPTCompleter(shell=self),
# patch_stdout=patch_stdout), enable_history_search = self.enable_history_search,
enable_history_search=True,
style=self.style, style=self.style,
include_default_pygments_style=False,
mouse_support=self.mouse_support, mouse_support=self.mouse_support,
**self._layout_options() enable_open_in_editor=self.extra_open_editor_shortcuts,
) color_depth=(ColorDepth.TRUE_COLOR if self.true_color else None),
self._eventloop = create_eventloop(self.inputhook) **self._extra_prompt_options())
self.pt_cli = CommandLineInterface(
self._pt_app, eventloop=self._eventloop,
output=create_output(true_color=self.true_color))
def _make_style_from_name_or_cls(self, name_or_cls): def _make_style_from_name_or_cls(self, name_or_cls):
""" """
@ -309,9 +314,9 @@ class TerminalInteractiveShell(InteractiveShell):
Token.Name.Class: 'bold #2080D0', Token.Name.Class: 'bold #2080D0',
Token.Name.Namespace: 'bold #2080D0', Token.Name.Namespace: 'bold #2080D0',
Token.Prompt: '#009900', Token.Prompt: '#009900',
Token.PromptNum: '#00ff00 bold', Token.PromptNum: '#ansibrightgreen bold',
Token.OutPrompt: '#990000', Token.OutPrompt: '#990000',
Token.OutPromptNum: '#ff0000 bold', Token.OutPromptNum: '#ansibrightred bold',
}) })
# Hack: Due to limited color support on the Windows console # Hack: Due to limited color support on the Windows console
@ -335,49 +340,66 @@ class TerminalInteractiveShell(InteractiveShell):
style_cls = name_or_cls style_cls = name_or_cls
style_overrides = { style_overrides = {
Token.Prompt: '#009900', Token.Prompt: '#009900',
Token.PromptNum: '#00ff00 bold', Token.PromptNum: '#ansibrightgreen bold',
Token.OutPrompt: '#990000', Token.OutPrompt: '#990000',
Token.OutPromptNum: '#ff0000 bold', Token.OutPromptNum: '#ansibrightred bold',
} }
style_overrides.update(self.highlighting_style_overrides) style_overrides.update(self.highlighting_style_overrides)
style = PygmentsStyle.from_defaults(pygments_style_cls=style_cls, style = merge_styles([
style_dict=style_overrides) style_from_pygments_cls(style_cls),
style_from_pygments_dict(style_overrides),
])
return style return style
def _layout_options(self): @property
def pt_complete_style(self):
return {
'multicolumn': CompleteStyle.MULTI_COLUMN,
'column': CompleteStyle.COLUMN,
'readlinelike': CompleteStyle.READLINE_LIKE,
}[self.display_completions]
def _extra_prompt_options(self):
""" """
Return the current layout option for the current Terminal InteractiveShell Return the current layout option for the current Terminal InteractiveShell
""" """
def get_message():
return PygmentsTokens(self.prompts.in_prompt_tokens())
return { return {
'complete_in_thread': False,
'lexer':IPythonPTLexer(), 'lexer':IPythonPTLexer(),
'reserve_space_for_menu':self.space_for_menu, 'reserve_space_for_menu':self.space_for_menu,
'get_prompt_tokens':self.prompts.in_prompt_tokens, 'message': get_message,
'get_continuation_tokens':self.prompts.continuation_prompt_tokens, 'prompt_continuation': (
'multiline':True, lambda width, lineno, is_soft_wrap:
'display_completions_in_columns': (self.display_completions == 'multicolumn'), PygmentsTokens(self.prompts.continuation_prompt_tokens(width))),
'multiline': True,
'complete_style': self.pt_complete_style,
# Highlight matching brackets, but only when this setting is # Highlight matching brackets, but only when this setting is
# enabled, and only when the DEFAULT_BUFFER has the focus. # enabled, and only when the DEFAULT_BUFFER has the focus.
'extra_input_processors': [ConditionalProcessor( 'input_processors': [ConditionalProcessor(
processor=HighlightMatchingBracketProcessor(chars='[](){}'), processor=HighlightMatchingBracketProcessor(chars='[](){}'),
filter=HasFocus(DEFAULT_BUFFER) & ~IsDone() & filter=HasFocus(DEFAULT_BUFFER) & ~IsDone() &
Condition(lambda cli: self.highlight_matching_brackets))], Condition(lambda: self.highlight_matching_brackets))],
'inputhook': self.inputhook,
} }
def _update_layout(self):
"""
Ask for a re computation of the application layout, if for example ,
some configuration options have changed.
"""
if self._pt_app:
self._pt_app.layout = create_prompt_layout(**self._layout_options())
def prompt_for_code(self): def prompt_for_code(self):
with self.pt_cli.patch_stdout_context(raw=True): if self.rl_next_input:
document = self.pt_cli.run( default = self.rl_next_input
pre_run=self.pre_prompt, reset_current_buffer=True) self.rl_next_input = None
return document.text else:
default = ''
with patch_stdout(raw=True):
text = self.pt_app.prompt(
default=default,
# pre_run=self.pre_prompt,# reset_current_buffer=True,
**self._extra_prompt_options())
return text
def enable_win_unicode_console(self): def enable_win_unicode_console(self):
if sys.version_info >= (3, 6): if sys.version_info >= (3, 6):
@ -437,22 +459,6 @@ class TerminalInteractiveShell(InteractiveShell):
rl_next_input = None rl_next_input = None
def pre_prompt(self):
if self.rl_next_input:
# We can't set the buffer here, because it will be reset just after
# this. Adding a callable to pre_run_callables does what we need
# after the buffer is reset.
s = self.rl_next_input
def set_doc():
self.pt_cli.application.buffer.document = Document(s)
if hasattr(self.pt_cli, 'pre_run_callables'):
self.pt_cli.pre_run_callables.append(set_doc)
else:
# Older version of prompt_toolkit; it's OK to set the document
# directly here.
set_doc()
self.rl_next_input = None
def interact(self, display_banner=DISPLAY_BANNER_DEPRECATED): def interact(self, display_banner=DISPLAY_BANNER_DEPRECATED):
if display_banner is not DISPLAY_BANNER_DEPRECATED: if display_banner is not DISPLAY_BANNER_DEPRECATED:
@ -477,7 +483,7 @@ class TerminalInteractiveShell(InteractiveShell):
# An extra layer of protection in case someone mashing Ctrl-C breaks # An extra layer of protection in case someone mashing Ctrl-C breaks
# out of our internal code. # out of our internal code.
if display_banner is not DISPLAY_BANNER_DEPRECATED: if display_banner is not DISPLAY_BANNER_DEPRECATED:
warn('mainloop `display_banner` argument is deprecated since yap_ipython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2) warn('mainloop `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2)
while True: while True:
try: try:
self.interact() self.interact()
@ -515,8 +521,9 @@ class TerminalInteractiveShell(InteractiveShell):
return return
tokens = self.prompts.rewrite_prompt_tokens() tokens = self.prompts.rewrite_prompt_tokens()
if self.pt_cli: if self.pt_app:
self.pt_cli.print_tokens(tokens) print_formatted_text(PygmentsTokens(tokens), end='',
style=self.pt_app.app.style)
print(cmd) print(cmd)
else: else:
prompt = ''.join(s for t, s in tokens) prompt = ''.join(s for t, s in tokens)
@ -531,7 +538,7 @@ class TerminalInteractiveShell(InteractiveShell):
elif self._prompts_before: elif self._prompts_before:
self.prompts = self._prompts_before self.prompts = self._prompts_before
self._prompts_before = None self._prompts_before = None
self._update_layout() # self._update_layout()
InteractiveShellABC.register(TerminalInteractiveShell) InteractiveShellABC.register(TerminalInteractiveShell)

View File

@ -18,7 +18,7 @@ from traitlets.config.loader import Config
from traitlets.config.application import boolean_flag, catch_config_error from traitlets.config.application import boolean_flag, catch_config_error
from yap_ipython.core import release from yap_ipython.core import release
from yap_ipython.core import usage from yap_ipython.core import usage
from yap_ipython.yapi import YAPCompleter from yap_ipython.core.completer import IPCompleter
from yap_ipython.core.crashhandler import CrashHandler from yap_ipython.core.crashhandler import CrashHandler
from yap_ipython.core.formatters import PlainTextFormatter from yap_ipython.core.formatters import PlainTextFormatter
from yap_ipython.core.history import HistoryManager from yap_ipython.core.history import HistoryManager
@ -106,7 +106,7 @@ addflag('simple-prompt', 'TerminalInteractiveShell.simple_prompt',
"Use a rich interactive prompt with prompt_toolkit", "Use a rich interactive prompt with prompt_toolkit",
) )
addflag('banner', 'TerminalIPythonApp.display_banner', addflag('banner', 'Terminalyap_ipythonApp.display_banner',
"Display a banner upon starting yap_ipython.", "Display a banner upon starting yap_ipython.",
"Don't display a banner upon starting yap_ipython." "Don't display a banner upon starting yap_ipython."
) )
@ -141,12 +141,12 @@ frontend_flags['classic']=(
# #
# # quick is harder to implement # # quick is harder to implement
frontend_flags['quick']=( frontend_flags['quick']=(
{'TerminalIPythonApp' : {'quick' : True}}, {'Terminalyap_ipythonApp' : {'quick' : True}},
"Enable quick startup with no config files." "Enable quick startup with no config files."
) )
frontend_flags['i'] = ( frontend_flags['i'] = (
{'TerminalIPythonApp' : {'force_interact' : True}}, {'Terminalyap_ipythonApp' : {'force_interact' : True}},
"""If running code from the command line, become interactive afterwards. """If running code from the command line, become interactive afterwards.
It is often useful to follow this with `--` to treat remaining flags as It is often useful to follow this with `--` to treat remaining flags as
script arguments. script arguments.
@ -162,7 +162,7 @@ aliases.update(shell_aliases)
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
class LocateIPythonApp(BaseYAPApplication): class Locateyap_ipythonApp(BaseYAPApplication):
description = """print the path to the yap_ipython dir""" description = """print the path to the yap_ipython dir"""
subcommands = dict( subcommands = dict(
profile=('yap_ipython.core.profileapp.ProfileLocate', profile=('yap_ipython.core.profileapp.ProfileLocate',
@ -176,8 +176,8 @@ class LocateIPythonApp(BaseYAPApplication):
print(self.ipython_dir) print(self.ipython_dir)
class TerminalIPythonApp(BaseYAPApplication, InteractiveShellApp): class Terminalyap_ipythonApp(BaseYAPApplication, InteractiveShellApp):
name = u'yap' name = u'ipython'
description = usage.cl_usage description = usage.cl_usage
crash_handler_class = IPAppCrashHandler crash_handler_class = IPAppCrashHandler
examples = _examples examples = _examples
@ -194,7 +194,7 @@ class TerminalIPythonApp(BaseYAPApplication, InteractiveShellApp):
@default('classes') @default('classes')
def _classes_default(self): def _classes_default(self):
"""This has to be in a method, for TerminalIPythonApp to be available.""" """This has to be in a method, for Terminalyap_ipythonApp to be available."""
return [ return [
InteractiveShellApp, # ShellApp comes before TerminalApp, because InteractiveShellApp, # ShellApp comes before TerminalApp, because
self.__class__, # it will also affect subclasses (e.g. QtConsole) self.__class__, # it will also affect subclasses (e.g. QtConsole)
@ -202,7 +202,7 @@ class TerminalIPythonApp(BaseYAPApplication, InteractiveShellApp):
HistoryManager, HistoryManager,
ProfileDir, ProfileDir,
PlainTextFormatter, PlainTextFormatter,
YAPCompleter, IPCompleter,
ScriptMagics, ScriptMagics,
LoggingMagics, LoggingMagics,
StoreMagics, StoreMagics,
@ -215,7 +215,7 @@ class TerminalIPythonApp(BaseYAPApplication, InteractiveShellApp):
notebook=('notebook.notebookapp.NotebookApp', notebook=('notebook.notebookapp.NotebookApp',
"""DEPRECATED, Will be removed in yap_ipython 6.0 : Launch the Jupyter HTML Notebook Server.""" """DEPRECATED, Will be removed in yap_ipython 6.0 : Launch the Jupyter HTML Notebook Server."""
), ),
console=('jupyter_console.app.ZMQTerminalIPythonApp', console=('jupyter_console.app.ZMQTerminalyap_ipythonApp',
"""DEPRECATED, Will be removed in yap_ipython 6.0 : Launch the Jupyter terminal-based Console.""" """DEPRECATED, Will be removed in yap_ipython 6.0 : Launch the Jupyter terminal-based Console."""
), ),
nbconvert=('nbconvert.nbconvertapp.NbConvertApp', nbconvert=('nbconvert.nbconvertapp.NbConvertApp',
@ -232,11 +232,11 @@ class TerminalIPythonApp(BaseYAPApplication, InteractiveShellApp):
profile = ("yap_ipython.core.profileapp.ProfileApp", profile = ("yap_ipython.core.profileapp.ProfileApp",
"Create and manage yap_ipython profiles." "Create and manage yap_ipython profiles."
), ),
kernel = ("yap_kernel.kernelapp.YAPKernelApp", kernel = ("ipykernel.kernelapp.IPKernelApp",
"Start a kernel without an attached frontend." "Start a kernel without an attached frontend."
), ),
locate=('yap_ipython.terminal.ipapp.LocateIPythonApp', locate=('yap_ipython.terminal.ipapp.Locateyap_ipythonApp',
LocateIPythonApp.description Locateyap_ipythonApp.description
), ),
history=('yap_ipython.core.historyapp.HistoryApp', history=('yap_ipython.core.historyapp.HistoryApp',
"Manage the yap_ipython history database." "Manage the yap_ipython history database."
@ -300,12 +300,12 @@ class TerminalIPythonApp(BaseYAPApplication, InteractiveShellApp):
" Use `--matplotlib <backend>` and import pylab manually.") " Use `--matplotlib <backend>` and import pylab manually.")
argv[idx] = '--pylab' argv[idx] = '--pylab'
return super(TerminalIPythonApp, self).parse_command_line(argv) return super(Terminalyap_ipythonApp, self).parse_command_line(argv)
@catch_config_error @catch_config_error
def initialize(self, argv=None): def initialize(self, argv=None):
"""Do actions after construct, but before starting the app.""" """Do actions after construct, but before starting the app."""
super(TerminalIPythonApp, self).initialize(argv) super(Terminalyap_ipythonApp, self).initialize(argv)
if self.subapp is not None: if self.subapp is not None:
# don't bother initializing further, starting subapp # don't bother initializing further, starting subapp
return return
@ -368,12 +368,12 @@ def load_default_config(ipython_dir=None):
ipython_dir = get_ipython_dir() ipython_dir = get_ipython_dir()
profile_dir = os.path.join(ipython_dir, 'profile_default') profile_dir = os.path.join(ipython_dir, 'profile_default')
app = TerminalIPythonApp() app = Terminalyap_ipythonApp()
app.config_file_paths.append(profile_dir) app.config_file_paths.append(profile_dir)
app.load_config_file() app.load_config_file()
return app.config return app.config
launch_new_instance = TerminalIPythonApp.launch_instance launch_new_instance = Terminalyap_ipythonApp.launch_instance
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -9,7 +9,6 @@ import os
import sys import sys
from yap_ipython.core.error import TryNext, UsageError from yap_ipython.core.error import TryNext, UsageError
from yap_ipython.core.inputsplitter import IPythonInputSplitter
from yap_ipython.core.magic import Magics, magics_class, line_magic from yap_ipython.core.magic import Magics, magics_class, line_magic
from yap_ipython.lib.clipboard import ClipboardEmpty from yap_ipython.lib.clipboard import ClipboardEmpty
from yap_ipython.utils.text import SList, strip_email_quotes from yap_ipython.utils.text import SList, strip_email_quotes
@ -40,7 +39,6 @@ def get_pasted_lines(sentinel, l_input=py3compat.input, quiet=False):
class TerminalMagics(Magics): class TerminalMagics(Magics):
def __init__(self, shell): def __init__(self, shell):
super(TerminalMagics, self).__init__(shell) super(TerminalMagics, self).__init__(shell)
self.input_splitter = IPythonInputSplitter()
def store_or_execute(self, block, name): def store_or_execute(self, block, name):
""" Execute a block, or store it in a variable, per the user's request. """ Execute a block, or store it in a variable, per the user's request.
@ -82,8 +80,6 @@ class TerminalMagics(Magics):
@line_magic @line_magic
def autoindent(self, parameter_s = ''): def autoindent(self, parameter_s = ''):
"""Toggle autoindent on/off (deprecated)""" """Toggle autoindent on/off (deprecated)"""
print("%autoindent is deprecated since yap_ipython 5: you can now paste "
"multiple lines without turning autoindentation off.")
self.shell.set_autoindent() self.shell.set_autoindent()
print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent]) print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])

View File

@ -5,23 +5,34 @@ import sys
from yap_ipython.core.displayhook import DisplayHook from yap_ipython.core.displayhook import DisplayHook
from prompt_toolkit.layout.utils import token_list_width from prompt_toolkit.formatted_text import fragment_list_width, PygmentsTokens
from prompt_toolkit.shortcuts import print_formatted_text
class Prompts(object): class Prompts(object):
def __init__(self, shell): def __init__(self, shell):
self.shell = shell self.shell = shell
def in_prompt_tokens(self, cli=None): def vi_mode(self):
if not hasattr(self.shell.pt_app, 'editing_mode'):
return ''
if self.shell.pt_app.editing_mode == 'VI':
return '['+str(self.shell.pt_app.app.vi_state.input_mode)[3:6]+'] '
return ''
def in_prompt_tokens(self):
return [ return [
(Token.Prompt, self.vi_mode() ),
(Token.Prompt, 'In ['), (Token.Prompt, 'In ['),
(Token.PromptNum, str(self.shell.execution_count)), (Token.PromptNum, str(self.shell.execution_count)),
(Token.Prompt, ']: '), (Token.Prompt, ']: '),
] ]
def _width(self): def _width(self):
return token_list_width(self.in_prompt_tokens()) return fragment_list_width(self.in_prompt_tokens())
def continuation_prompt_tokens(self, cli=None, width=None): def continuation_prompt_tokens(self, width=None):
if width is None: if width is None:
width = self._width() width = self._width()
return [ return [
@ -42,12 +53,12 @@ class Prompts(object):
] ]
class ClassicPrompts(Prompts): class ClassicPrompts(Prompts):
def in_prompt_tokens(self, cli=None): def in_prompt_tokens(self):
return [ return [
(Token.Prompt, '>>> '), (Token.Prompt, '>>> '),
] ]
def continuation_prompt_tokens(self, cli=None, width=None): def continuation_prompt_tokens(self, width=None):
return [ return [
(Token.Prompt, '... ') (Token.Prompt, '... ')
] ]
@ -73,7 +84,9 @@ class RichPromptDisplayHook(DisplayHook):
# Ask for a newline before multiline output # Ask for a newline before multiline output
self.prompt_end_newline = False self.prompt_end_newline = False
if self.shell.pt_cli: if self.shell.pt_app:
self.shell.pt_cli.print_tokens(tokens) print_formatted_text(PygmentsTokens(tokens),
style=self.shell.pt_app.app.style, end='',
)
else: else:
sys.stdout.write(prompt_txt) sys.stdout.write(prompt_txt)

View File

@ -45,5 +45,5 @@ def get_inputhook_name_and_func(gui):
os.environ['QT_API'] = 'pyqt5' os.environ['QT_API'] = 'pyqt5'
gui_mod = 'qt' gui_mod = 'qt'
mod = importlib.import_module('yap_ipython.terminal.pt_inputhooks.'+gui_mod) mod = importlib.import_module('IPython.terminal.pt_inputhooks.'+gui_mod)
return gui, mod.inputhook return gui, mod.inputhook

View File

@ -3,7 +3,7 @@
# GLUT is quite an old library and it is difficult to ensure proper # GLUT is quite an old library and it is difficult to ensure proper
# integration within yap_ipython since original GLUT does not allow to handle # integration within IPython since original GLUT does not allow to handle
# events one by one. Instead, it requires for the mainloop to be entered # events one by one. Instead, it requires for the mainloop to be entered
# and never returned (there is not even a function to exit he # and never returned (there is not even a function to exit he
# mainloop). Fortunately, there are alternatives such as freeglut # mainloop). Fortunately, there are alternatives such as freeglut
@ -16,7 +16,7 @@
# being first created. We choose to make this window invisible. This means that # being first created. We choose to make this window invisible. This means that
# display mode options are set at this level and user won't be able to change # display mode options are set at this level and user won't be able to change
# them later without modifying the code. This should probably be made available # them later without modifying the code. This should probably be made available
# via yap_ipython options system. # via IPython options system.
import sys import sys
import time import time
@ -26,11 +26,11 @@ import OpenGL.platform as platform
from timeit import default_timer as clock from timeit import default_timer as clock
# Frame per second : 60 # Frame per second : 60
# Should probably be an yap_ipython option # Should probably be an IPython option
glut_fps = 60 glut_fps = 60
# Display mode : double buffeed + rgba + depth # Display mode : double buffeed + rgba + depth
# Should probably be an yap_ipython option # Should probably be an IPython option
glut_display_mode = (glut.GLUT_DOUBLE | glut_display_mode = (glut.GLUT_DOUBLE |
glut.GLUT_RGBA | glut.GLUT_RGBA |
glut.GLUT_DEPTH) glut.GLUT_DEPTH)
@ -99,7 +99,7 @@ def inputhook(context):
needed, otherwise, CPU usage is at 100%. This sleep time should be tuned needed, otherwise, CPU usage is at 100%. This sleep time should be tuned
though for best performance. though for best performance.
""" """
# We need to protect against a user pressing Control-C when yap_ipython is # We need to protect against a user pressing Control-C when IPython is
# idle and this is running. We trap KeyboardInterrupt and pass. # idle and this is running. We trap KeyboardInterrupt and pass.
signal.signal(signal.SIGINT, glut_int_handler) signal.signal(signal.SIGINT, glut_int_handler)

View File

@ -1,4 +1,4 @@
"""Enable pyglet to be used interacively with prompt_toolkit """Enable pyglet to be used interactively with prompt_toolkit
""" """
import sys import sys
@ -29,7 +29,7 @@ def inputhook(context):
needed, otherwise, CPU usage is at 100%. This sleep time should be tuned needed, otherwise, CPU usage is at 100%. This sleep time should be tuned
though for best performance. though for best performance.
""" """
# We need to protect against a user pressing Control-C when yap_ipython is # We need to protect against a user pressing Control-C when IPython is
# idle and this is running. We trap KeyboardInterrupt and pass. # idle and this is running. We trap KeyboardInterrupt and pass.
try: try:
t = clock() t = clock()

View File

@ -1,15 +1,29 @@
import sys import sys
from yap_ipython.external.qt_for_kernel import QtCore, QtGui import os
from IPython.external.qt_for_kernel import QtCore, QtGui
# If we create a QApplication, keep a reference to it so that it doesn't get # If we create a QApplication, keep a reference to it so that it doesn't get
# garbage collected. # garbage collected.
_appref = None _appref = None
_already_warned = False
def inputhook(context): def inputhook(context):
global _appref global _appref
app = QtCore.QCoreApplication.instance() app = QtCore.QCoreApplication.instance()
if not app: if not app:
if sys.platform == 'linux':
if not os.environ.get('DISPLAY') \
and not os.environ.get('WAYLAND_DISPLAY'):
import warnings
global _already_warned
if not _already_warned:
_already_warned = True
warnings.warn(
'The DISPLAY or WAYLAND_DISPLAY environment variable is '
'not set or empty and Qt5 requires this environment '
'variable. Deactivate Qt5 code.'
)
return
_appref = app = QtGui.QApplication([" "]) _appref = app = QtGui.QApplication([" "])
event_loop = QtCore.QEventLoop(app) event_loop = QtCore.QEventLoop(app)

View File

@ -90,7 +90,7 @@ def inputhook_wx3(context):
time.sleep is inserted. This is needed, otherwise, CPU usage is at 100%. time.sleep is inserted. This is needed, otherwise, CPU usage is at 100%.
This sleep time should be tuned though for best performance. This sleep time should be tuned though for best performance.
""" """
# We need to protect against a user pressing Control-C when yap_ipython is # We need to protect against a user pressing Control-C when IPython is
# idle and this is running. We trap KeyboardInterrupt and pass. # idle and this is running. We trap KeyboardInterrupt and pass.
try: try:
app = wx.GetApp() app = wx.GetApp()

View File

@ -1,8 +1,8 @@
raise DeprecationWarning("""DEPRECATED: raise DeprecationWarning("""DEPRECATED:
After Popular request and decision from the BDFL: After Popular request and decision from the BDFL:
`yap_ipython.terminal.ptshell` has been moved back to `yap_ipython.terminal.interactiveshell` `IPython.terminal.ptshell` has been moved back to `IPython.terminal.interactiveshell`
during the beta cycle (after yap_ipython 5.0.beta3) Sorry about that. during the beta cycle (after IPython 5.0.beta3) Sorry about that.
This file will be removed in 5.0 rc or final. This file will be removed in 5.0 rc or final.
""") """)

View File

@ -1,21 +1,22 @@
"""prompt-toolkit utilities """prompt-toolkit utilities
Everything in this module is a private API, Everything in this module is a private API,
not to be used outside yap_ipython. not to be used outside IPython.
""" """
# Copyright (c) yap_ipython Development Team. # Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License. # Distributed under the terms of the Modified BSD License.
import unicodedata import unicodedata
from wcwidth import wcwidth from wcwidth import wcwidth
from yap_ipython.core.completer import ( from IPython.core.completer import (
provisionalcompleter, cursor_to_position, provisionalcompleter, cursor_to_position,
_deduplicate_completions) _deduplicate_completions)
from prompt_toolkit.completion import Completer, Completion from prompt_toolkit.completion import Completer, Completion
from prompt_toolkit.layout.lexers import Lexer from prompt_toolkit.lexers import Lexer
from prompt_toolkit.layout.lexers import PygmentsLexer from prompt_toolkit.lexers import PygmentsLexer
from prompt_toolkit.patch_stdout import patch_stdout
import pygments.lexers as pygments_lexers import pygments.lexers as pygments_lexers
@ -51,15 +52,12 @@ def _adjust_completion_text_based_on_context(text, body, offset):
class IPythonPTCompleter(Completer): class IPythonPTCompleter(Completer):
"""Adaptor to provide yap_ipython completions to prompt_toolkit""" """Adaptor to provide IPython completions to prompt_toolkit"""
def __init__(self, ipy_completer=None, shell=None, patch_stdout=None): def __init__(self, ipy_completer=None, shell=None):
if shell is None and ipy_completer is None: if shell is None and ipy_completer is None:
raise TypeError("Please pass shell=an InteractiveShell instance.") raise TypeError("Please pass shell=an InteractiveShell instance.")
self._ipy_completer = ipy_completer self._ipy_completer = ipy_completer
self.shell = shell self.shell = shell
if patch_stdout is None:
raise TypeError("Please pass patch_stdout")
self.patch_stdout = patch_stdout
@property @property
def ipy_completer(self): def ipy_completer(self):
@ -75,7 +73,7 @@ class IPythonPTCompleter(Completer):
# is imported). This context manager ensures that doesn't interfere with # is imported). This context manager ensures that doesn't interfere with
# the prompt. # the prompt.
with self.patch_stdout(), provisionalcompleter(): with patch_stdout(), provisionalcompleter():
body = document.text body = document.text
cursor_row = document.cursor_position_row cursor_row = document.cursor_position_row
cursor_col = document.cursor_position_col cursor_col = document.cursor_position_col
@ -143,7 +141,7 @@ class IPythonPTLexer(Lexer):
'latex': PygmentsLexer(l.TexLexer), 'latex': PygmentsLexer(l.TexLexer),
} }
def lex_document(self, cli, document): def lex_document(self, document):
text = document.text.lstrip() text = document.text.lstrip()
lexer = self.python_lexer lexer = self.python_lexer
@ -157,4 +155,4 @@ class IPythonPTLexer(Lexer):
lexer = l lexer = l
break break
return lexer.lex_document(cli, document) return lexer.lex_document(document)

View File

@ -1,9 +1,9 @@
""" """
Module to define and register Terminal yap_ipython shortcuts with Module to define and register Terminal IPython shortcuts with
:mod:`prompt_toolkit` :mod:`prompt_toolkit`
""" """
# Copyright (c) yap_ipython Development Team. # Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License. # Distributed under the terms of the Modified BSD License.
import warnings import warnings
@ -12,91 +12,78 @@ import sys
from typing import Callable from typing import Callable
from prompt_toolkit.application.current import get_app
from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER
from prompt_toolkit.filters import (HasFocus, HasSelection, Condition, from prompt_toolkit.filters import (has_focus, has_selection, Condition,
ViInsertMode, EmacsInsertMode, HasCompletions) vi_insert_mode, emacs_insert_mode, has_completions, vi_mode)
from prompt_toolkit.filters.cli import ViMode, ViNavigationMode
from prompt_toolkit.keys import Keys
from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline
from prompt_toolkit.key_binding import KeyBindings
from yap_ipython.utils.decorators import undoc from IPython.utils.decorators import undoc
@undoc @undoc
@Condition @Condition
def cursor_in_leading_ws(cli): def cursor_in_leading_ws():
before = cli.application.buffer.document.current_line_before_cursor before = get_app().current_buffer.document.current_line_before_cursor
return (not before) or before.isspace() return (not before) or before.isspace()
def register_ipython_shortcuts(registry, shell):
"""Set up the prompt_toolkit keyboard shortcuts for yap_ipython""" def create_ipython_shortcuts(shell):
insert_mode = ViInsertMode() | EmacsInsertMode() """Set up the prompt_toolkit keyboard shortcuts for IPython"""
kb = KeyBindings()
insert_mode = vi_insert_mode | emacs_insert_mode
if getattr(shell, 'handle_return', None): if getattr(shell, 'handle_return', None):
return_handler = shell.handle_return(shell) return_handler = shell.handle_return(shell)
else: else:
return_handler = newline_or_execute_outer(shell) return_handler = newline_or_execute_outer(shell)
# Ctrl+J == Enter, seemingly kb.add('enter', filter=(has_focus(DEFAULT_BUFFER)
registry.add_binding(Keys.ControlJ, & ~has_selection
filter=(HasFocus(DEFAULT_BUFFER) & insert_mode
& ~HasSelection()
& insert_mode
))(return_handler) ))(return_handler)
registry.add_binding(Keys.ControlBackslash)(force_exit) kb.add('c-\\')(force_exit)
registry.add_binding(Keys.ControlP, kb.add('c-p', filter=(vi_insert_mode & has_focus(DEFAULT_BUFFER))
filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER) )(previous_history_or_previous_completion)
))(previous_history_or_previous_completion)
registry.add_binding(Keys.ControlN, kb.add('c-n', filter=(vi_insert_mode & has_focus(DEFAULT_BUFFER))
filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER) )(next_history_or_next_completion)
))(next_history_or_next_completion)
registry.add_binding(Keys.ControlG, kb.add('c-g', filter=(has_focus(DEFAULT_BUFFER) & has_completions)
filter=(HasFocus(DEFAULT_BUFFER) & HasCompletions() )(dismiss_completion)
))(dismiss_completion)
registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER) kb.add('c-c', filter=has_focus(DEFAULT_BUFFER))(reset_buffer)
)(reset_buffer)
registry.add_binding(Keys.ControlC, filter=HasFocus(SEARCH_BUFFER) kb.add('c-c', filter=has_focus(SEARCH_BUFFER))(reset_search_buffer)
)(reset_search_buffer)
supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP')) supports_suspend = Condition(lambda: hasattr(signal, 'SIGTSTP'))
registry.add_binding(Keys.ControlZ, filter=supports_suspend kb.add('c-z', filter=supports_suspend)(suspend_to_bg)
)(suspend_to_bg)
# Ctrl+I == Tab # Ctrl+I == Tab
registry.add_binding(Keys.ControlI, kb.add('tab', filter=(has_focus(DEFAULT_BUFFER)
filter=(HasFocus(DEFAULT_BUFFER) & ~has_selection
& ~HasSelection() & insert_mode
& insert_mode & cursor_in_leading_ws
& cursor_in_leading_ws
))(indent_buffer) ))(indent_buffer)
kb.add('c-o', filter=(has_focus(DEFAULT_BUFFER) & emacs_insert_mode)
)(newline_autoindent_outer(shell.input_transformer_manager))
registry.add_binding(Keys.ControlO, kb.add('f2', filter=has_focus(DEFAULT_BUFFER))(open_input_in_editor)
filter=(HasFocus(DEFAULT_BUFFER)
& EmacsInsertMode()))(newline_autoindent_outer(shell.input_splitter))
registry.add_binding(Keys.F2,
filter=HasFocus(DEFAULT_BUFFER)
)(open_input_in_editor)
if shell.display_completions == 'readlinelike': if shell.display_completions == 'readlinelike':
registry.add_binding(Keys.ControlI, kb.add('c-i', filter=(has_focus(DEFAULT_BUFFER)
filter=(HasFocus(DEFAULT_BUFFER) & ~has_selection
& ~HasSelection() & insert_mode
& insert_mode & ~cursor_in_leading_ws
& ~cursor_in_leading_ws ))(display_completions_like_readline)
))(display_completions_like_readline)
if sys.platform == 'win32': if sys.platform == 'win32':
registry.add_binding(Keys.ControlV, kb.add('c-v', filter=(has_focus(DEFAULT_BUFFER) & ~vi_mode))(win_paste)
filter=(
HasFocus( return kb
DEFAULT_BUFFER) & ~ViMode()
))(win_paste)
def newline_or_execute_outer(shell): def newline_or_execute_outer(shell):
@ -119,18 +106,24 @@ def newline_or_execute_outer(shell):
check_text = d.text check_text = d.text
else: else:
check_text = d.text[:d.cursor_position] check_text = d.text[:d.cursor_position]
status, indent = shell.input_splitter.check_complete(check_text + '\n') status, indent = shell.check_complete(check_text)
if not (d.on_last_line or if not (d.on_last_line or
d.cursor_position_row >= d.line_count - d.empty_line_count_at_the_end() d.cursor_position_row >= d.line_count - d.empty_line_count_at_the_end()
): ):
b.insert_text('\n' + (' ' * (indent or 0))) if shell.autoindent:
b.insert_text('\n' + indent)
else:
b.insert_text('\n')
return return
if (status != 'incomplete') and b.accept_action.is_returnable: if (status != 'incomplete') and b.accept_handler:
b.accept_action.validate_and_handle(event.cli, b) b.validate_and_handle()
else: else:
b.insert_text('\n' + (' ' * (indent or 0))) if shell.autoindent:
b.insert_text('\n' + indent)
else:
b.insert_text('\n')
return newline_or_execute return newline_or_execute
@ -170,10 +163,10 @@ def reset_search_buffer(event):
if event.current_buffer.document.text: if event.current_buffer.document.text:
event.current_buffer.reset() event.current_buffer.reset()
else: else:
event.cli.push_focus(DEFAULT_BUFFER) event.app.layout.focus(DEFAULT_BUFFER)
def suspend_to_bg(event): def suspend_to_bg(event):
event.cli.suspend_to_background() event.app.suspend_to_background()
def force_exit(event): def force_exit(event):
""" """
@ -187,14 +180,14 @@ def indent_buffer(event):
@undoc @undoc
def newline_with_copy_margin(event): def newline_with_copy_margin(event):
""" """
DEPRECATED since yap_ipython 6.0 DEPRECATED since IPython 6.0
See :any:`newline_autoindent_outer` for a replacement. See :any:`newline_autoindent_outer` for a replacement.
Preserve margin and cursor position when using Preserve margin and cursor position when using
Control-O to insert a newline in EMACS mode Control-O to insert a newline in EMACS mode
""" """
warnings.warn("`newline_with_copy_margin(event)` is deprecated since yap_ipython 6.0. " warnings.warn("`newline_with_copy_margin(event)` is deprecated since IPython 6.0. "
"see `newline_autoindent_outer(shell)(event)` for a replacement.", "see `newline_autoindent_outer(shell)(event)` for a replacement.",
DeprecationWarning, stacklevel=2) DeprecationWarning, stacklevel=2)
@ -232,13 +225,13 @@ def newline_autoindent_outer(inputsplitter) -> Callable[..., None]:
def open_input_in_editor(event): def open_input_in_editor(event):
event.cli.current_buffer.tempfile_suffix = ".py" event.app.current_buffer.tempfile_suffix = ".py"
event.cli.current_buffer.open_in_editor(event.cli) event.app.current_buffer.open_in_editor()
if sys.platform == 'win32': if sys.platform == 'win32':
from yap_ipython.core.error import TryNext from IPython.core.error import TryNext
from yap_ipython.lib.clipboard import (ClipboardEmpty, from IPython.lib.clipboard import (ClipboardEmpty,
win32_clipboard_get, win32_clipboard_get,
tkinter_clipboard_get) tkinter_clipboard_get)

View File

@ -1,7 +1,7 @@
"""Test embedding of yap_ipython""" """Test embedding of IPython"""
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Copyright (C) 2013 The yap_ipython Development Team # Copyright (C) 2013 The IPython Development Team
# #
# Distributed under the terms of the BSD License. The full license is in # Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software. # the file COPYING, distributed as part of this software.
@ -15,8 +15,8 @@ import os
import subprocess import subprocess
import sys import sys
import nose.tools as nt import nose.tools as nt
from yap_ipython.utils.tempdir import NamedFileInTemporaryDirectory from IPython.utils.tempdir import NamedFileInTemporaryDirectory
from yap_ipython.testing.decorators import skip_win32 from IPython.testing.decorators import skip_win32
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Tests # Tests
@ -24,13 +24,13 @@ from yap_ipython.testing.decorators import skip_win32
_sample_embed = b""" _sample_embed = b"""
import yap_ipython import IPython
a = 3 a = 3
b = 14 b = 14
print(a, '.', b) print(a, '.', b)
yap_ipython.embed() IPython.embed()
print('bye!') print('bye!')
""" """
@ -38,7 +38,7 @@ print('bye!')
_exit = b"exit\r" _exit = b"exit\r"
def test_ipython_embed(): def test_ipython_embed():
"""test that `yap_ipython.embed()` works""" """test that `IPython.embed()` works"""
with NamedFileInTemporaryDirectory('file_with_embed.py') as f: with NamedFileInTemporaryDirectory('file_with_embed.py') as f:
f.write(_sample_embed) f.write(_sample_embed)
f.flush() f.flush()
@ -58,26 +58,27 @@ def test_ipython_embed():
nt.assert_in('3 . 14', std) nt.assert_in('3 . 14', std)
if os.name != 'nt': if os.name != 'nt':
# TODO: Fix up our different stdout references, see issue gh-14 # TODO: Fix up our different stdout references, see issue gh-14
nt.assert_in('yap_ipython', std) nt.assert_in('IPython', std)
nt.assert_in('bye!', std) nt.assert_in('bye!', std)
@skip_win32 @skip_win32
def test_nest_embed(): def test_nest_embed():
"""test that `yap_ipython.embed()` is nestable""" """test that `IPython.embed()` is nestable"""
import pexpect import pexpect
ipy_prompt = r']:' #ansi color codes give problems matching beyond this ipy_prompt = r']:' #ansi color codes give problems matching beyond this
env = os.environ.copy() env = os.environ.copy()
env['IPY_TEST_SIMPLE_PROMPT'] = '1' env['IPY_TEST_SIMPLE_PROMPT'] = '1'
child = pexpect.spawn(sys.executable, ['-m', 'yap_ipython', '--colors=nocolor'], child = pexpect.spawn(sys.executable, ['-m', 'IPython', '--colors=nocolor'],
env=env) env=env)
child.timeout = 5
child.expect(ipy_prompt) child.expect(ipy_prompt)
child.sendline("import yap_ipython") child.sendline("import IPython")
child.expect(ipy_prompt) child.expect(ipy_prompt)
child.sendline("ip0 = get_ipython()") child.sendline("ip0 = get_ipython()")
#enter first nested embed #enter first nested embed
child.sendline("yap_ipython.embed()") child.sendline("IPython.embed()")
#skip the banner until we get to a prompt #skip the banner until we get to a prompt
try: try:
prompted = -1 prompted = -1
@ -86,15 +87,16 @@ def test_nest_embed():
except pexpect.TIMEOUT as e: except pexpect.TIMEOUT as e:
print(e) print(e)
#child.interact() #child.interact()
child.sendline("embed1 = get_ipython()"); child.expect(ipy_prompt) child.sendline("embed1 = get_ipython()")
child.expect(ipy_prompt)
child.sendline("print('true' if embed1 is not ip0 else 'false')") child.sendline("print('true' if embed1 is not ip0 else 'false')")
assert(child.expect(['true\r\n', 'false\r\n']) == 0) assert(child.expect(['true\r\n', 'false\r\n']) == 0)
child.expect(ipy_prompt) child.expect(ipy_prompt)
child.sendline("print('true' if yap_ipython.get_ipython() is embed1 else 'false')") child.sendline("print('true' if IPython.get_ipython() is embed1 else 'false')")
assert(child.expect(['true\r\n', 'false\r\n']) == 0) assert(child.expect(['true\r\n', 'false\r\n']) == 0)
child.expect(ipy_prompt) child.expect(ipy_prompt)
#enter second nested embed #enter second nested embed
child.sendline("yap_ipython.embed()") child.sendline("IPython.embed()")
#skip the banner until we get to a prompt #skip the banner until we get to a prompt
try: try:
prompted = -1 prompted = -1
@ -103,11 +105,12 @@ def test_nest_embed():
except pexpect.TIMEOUT as e: except pexpect.TIMEOUT as e:
print(e) print(e)
#child.interact() #child.interact()
child.sendline("embed2 = get_ipython()"); child.expect(ipy_prompt) child.sendline("embed2 = get_ipython()")
child.expect(ipy_prompt)
child.sendline("print('true' if embed2 is not embed1 else 'false')") child.sendline("print('true' if embed2 is not embed1 else 'false')")
assert(child.expect(['true\r\n', 'false\r\n']) == 0) assert(child.expect(['true\r\n', 'false\r\n']) == 0)
child.expect(ipy_prompt) child.expect(ipy_prompt)
child.sendline("print('true' if embed2 is yap_ipython.get_ipython() else 'false')") child.sendline("print('true' if embed2 is IPython.get_ipython() else 'false')")
assert(child.expect(['true\r\n', 'false\r\n']) == 0) assert(child.expect(['true\r\n', 'false\r\n']) == 0)
child.expect(ipy_prompt) child.expect(ipy_prompt)
child.sendline('exit') child.sendline('exit')
@ -116,7 +119,7 @@ def test_nest_embed():
child.sendline("print('true' if get_ipython() is embed1 else 'false')") child.sendline("print('true' if get_ipython() is embed1 else 'false')")
assert(child.expect(['true\r\n', 'false\r\n']) == 0) assert(child.expect(['true\r\n', 'false\r\n']) == 0)
child.expect(ipy_prompt) child.expect(ipy_prompt)
child.sendline("print('true' if yap_ipython.get_ipython() is embed1 else 'false')") child.sendline("print('true' if IPython.get_ipython() is embed1 else 'false')")
assert(child.expect(['true\r\n', 'false\r\n']) == 0) assert(child.expect(['true\r\n', 'false\r\n']) == 0)
child.expect(ipy_prompt) child.expect(ipy_prompt)
child.sendline('exit') child.sendline('exit')
@ -125,7 +128,7 @@ def test_nest_embed():
child.sendline("print('true' if get_ipython() is ip0 else 'false')") child.sendline("print('true' if get_ipython() is ip0 else 'false')")
assert(child.expect(['true\r\n', 'false\r\n']) == 0) assert(child.expect(['true\r\n', 'false\r\n']) == 0)
child.expect(ipy_prompt) child.expect(ipy_prompt)
child.sendline("print('true' if yap_ipython.get_ipython() is ip0 else 'false')") child.sendline("print('true' if IPython.get_ipython() is ip0 else 'false')")
assert(child.expect(['true\r\n', 'false\r\n']) == 0) assert(child.expect(['true\r\n', 'false\r\n']) == 0)
child.expect(ipy_prompt) child.expect(ipy_prompt)
child.sendline('exit') child.sendline('exit')

View File

@ -1,9 +1,9 @@
"""Test help output of various yap_ipython entry points""" """Test help output of various IPython entry points"""
# Copyright (c) yap_ipython Development Team. # Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License. # Distributed under the terms of the Modified BSD License.
import yap_ipython.testing.tools as tt import IPython.testing.tools as tt
def test_ipython_help(): def test_ipython_help():

View File

@ -1,16 +1,16 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Tests for the TerminalInteractiveShell and related pieces.""" """Tests for the TerminalInteractiveShell and related pieces."""
# Copyright (c) yap_ipython Development Team. # Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License. # Distributed under the terms of the Modified BSD License.
import sys import sys
import unittest import unittest
from yap_ipython.core.inputtransformer import InputTransformer from IPython.core.inputtransformer import InputTransformer
from yap_ipython.testing import tools as tt from IPython.testing import tools as tt
from yap_ipython.utils.capture import capture_output from IPython.utils.capture import capture_output
from yap_ipython.terminal.ptutils import _elide, _adjust_completion_text_based_on_context from IPython.terminal.ptutils import _elide, _adjust_completion_text_based_on_context
import nose.tools as nt import nose.tools as nt
class TestElide(unittest.TestCase): class TestElide(unittest.TestCase):
@ -67,7 +67,7 @@ class mock_input_helper(object):
def mock_input(testfunc): def mock_input(testfunc):
"""Decorator for tests of the main interact loop. """Decorator for tests of the main interact loop.
Write the test as a generator, yield-ing the input strings, which yap_ipython Write the test as a generator, yield-ing the input strings, which IPython
will see as if they were typed in at the prompt. will see as if they were typed in at the prompt.
""" """
def test_method(self): def test_method(self):
@ -96,9 +96,7 @@ class InteractiveShellTestCase(unittest.TestCase):
@mock_input @mock_input
def test_inputtransformer_syntaxerror(self): def test_inputtransformer_syntaxerror(self):
ip = get_ipython() ip = get_ipython()
transformer = SyntaxErrorTransformer() ip.input_transformers_post.append(syntax_error_transformer)
ip.input_splitter.python_line_transforms.append(transformer)
ip.input_transformer_manager.python_line_transforms.append(transformer)
try: try:
#raise Exception #raise Exception
@ -112,8 +110,7 @@ class InteractiveShellTestCase(unittest.TestCase):
yield u'print(4*4)' yield u'print(4*4)'
finally: finally:
ip.input_splitter.python_line_transforms.remove(transformer) ip.input_transformers_post.remove(syntax_error_transformer)
ip.input_transformer_manager.python_line_transforms.remove(transformer)
def test_plain_text_only(self): def test_plain_text_only(self):
ip = get_ipython() ip = get_ipython()
@ -135,7 +132,7 @@ class InteractiveShellTestCase(unittest.TestCase):
class Test2(Test): class Test2(Test):
def _ipython_display_(self): def _ipython_display_(self):
from yap_ipython.display import display from IPython.display import display
display('<custom>') display('<custom>')
# verify that _ipython_display_ shortcut isn't called # verify that _ipython_display_ shortcut isn't called
@ -146,20 +143,17 @@ class InteractiveShellTestCase(unittest.TestCase):
self.assertEqual(data, {'text/plain': repr(obj)}) self.assertEqual(data, {'text/plain': repr(obj)})
assert captured.stdout == '' assert captured.stdout == ''
def syntax_error_transformer(lines):
"""Transformer that throws SyntaxError if 'syntaxerror' is in the code."""
class SyntaxErrorTransformer(InputTransformer): for line in lines:
def push(self, line):
pos = line.find('syntaxerror') pos = line.find('syntaxerror')
if pos >= 0: if pos >= 0:
e = SyntaxError('input contains "syntaxerror"') e = SyntaxError('input contains "syntaxerror"')
e.text = line e.text = line
e.offset = pos + 1 e.offset = pos + 1
raise e raise e
return line return lines
def reset(self):
pass
class TerminalMagicsTestCase(unittest.TestCase): class TerminalMagicsTestCase(unittest.TestCase):
def test_paste_magics_blankline(self): def test_paste_magics_blankline(self):

View File

@ -684,7 +684,7 @@ class YAPRun:
for i in self.errors: for i in self.errors:
try: try:
(_,lin,pos,text) = i (_,lin,pos,text) = i
e = SyntaxError(what, (self.cell_name, lin, pos, text+'\n')) e = self.SyntaxError( (self.cell_name, lin, pos, text+'\n'))
raise e raise e
except SyntaxError: except SyntaxError:
self.shell.showsyntaxerror( ) self.shell.showsyntaxerror( )
@ -723,7 +723,7 @@ class YAPRun:
# Give the displayhook a reference to our ExecutionResult so it # Give the displayhook a reference to our ExecutionResult so it
# can fill in the output value. # can fill in the output value.
self.shell.displayhook.exec_result = self.result self.shell.displayhook.exec_result = self.result
if syntaxErrors(self, text): if self.syntaxErrors(cell):
self.result.result = False self.result.result = False
has_raised = False has_raised = False
try: try:
@ -829,5 +829,5 @@ class YAPRun:
(query, _,loop, sols) = self.clean_end(query) (query, _,loop, sols) = self.clean_end(query)
return (program, query, loop, sols) return (program, query, loop, sols)
global # global
globals = {} #globals = {}

View File

@ -197,7 +197,7 @@ Prints a table with the current parameters. See the <a href="http://www.chokkan.
of libLBFGS</a> for the meaning of each parameter. of libLBFGS</a> for the meaning of each parameter.
~~~~ ~~~~
?- lbfgs_parameters. ?- lbfgs_parameters(State).
========================================================================================== ==========================================================================================
Type Name Value Description Type Name Value Description
========================================================================================== ==========================================================================================

View File

@ -95,5 +95,5 @@ endif()
install(FILES ${PL_BOOT_SOURCES} install(FILES ${PL_BOOT_SOURCES}
DESTINATION ${libpl}/pll DESTINATION ${libpl}/pl
) )

View File

@ -15,6 +15,10 @@
* * * *
*************************************************************************/ *************************************************************************/
/**
* @file checker.yap
*
*/
:- system_module( style_checker, [no_style_check/1, :- system_module( style_checker, [no_style_check/1,
style_check/1], ['$check_term'/5, style_check/1], ['$check_term'/5,
'$sv_warning'/2, '$sv_warning'/2,
@ -24,7 +28,7 @@
/** /**
@defgroup YAPStyle Checker @defgroup YAPStyleChecker Style Checker
@ingroup YAPCompilerSettings @ingroup YAPCompilerSettings
@{ @{
@ -167,6 +171,6 @@ separated by clauses from other procedures.
discontiguous(P) :- '$discontiguous'(P). discontiguous(P) :- '$discontiguous'(P).
/* /**
@} @}
*/ */

View File

@ -101,6 +101,10 @@ files and to set-up the Prolog environment. We discuss
+ @ref YAPCompilerSettings + @ref YAPCompilerSettings
@}
*/
/**
@defgroup YAPReadFiles The Predicates that Read Source Files @defgroup YAPReadFiles The Predicates that Read Source Files
@ingroup YAPConsulting @ingroup YAPConsulting
@ -1678,6 +1682,10 @@ End of conditional compilation.
current_prolog_flag(source, true), !. current_prolog_flag(source, true), !.
'$fetch_comp_status'(compact). '$fetch_comp_status'(compact).
/** consult_depth(-int:_LV_)
*
* Unify _LV_ with the number of files being consulted.
*/
consult_depth(LV) :- '$show_consult_level'(LV). consult_depth(LV) :- '$show_consult_level'(LV).
prolog_library(File) :- prolog_library(File) :-

View File

@ -41,7 +41,7 @@
/** /**
* @ingroup AttributedVariables_Builtins * @addtogroup AttributedVariables_Builtins
* @{ * @{
* *
* *
@ -141,42 +141,6 @@ freeze_goal(V,G) :-
'$current_module'(M), '$current_module'(M),
internal_freeze(V, redo_freeze(_Done,V,M:G)). internal_freeze(V, redo_freeze(_Done,V,M:G)).
%
%
% Dif is tricky because we need to wake up on the two variables being
% bound together, or on any variable of the term being bound to
% another. Also, the day YAP fully supports infinite rational trees,
% dif should work for them too. Hence, term comparison should not be
% implemented in Prolog.
%
% This is the way dif works. The '$can_unify' predicate does not know
% anything about dif semantics, it just compares two terms for
% equaility and is based on compare. If it succeeds without generating
% a list of variables, the terms are equal and dif fails. If it fails,
% dif succeeds.
%
% If it succeeds but it creates a list of variables, dif creates
% suspension records for all these variables on the '$redo_dif'(V,
% X, Y) goal. V is a flag that says whether dif has completed or not,
% X and Y are the original goals. Whenever one of these variables is
% bound, it calls '$redo_dif' again. '$redo_dif' will then check whether V
% was bound. If it was, dif has succeeded and redo_dif just
% exits. Otherwise, '$redo_dif' will call dif again to see what happened.
%
% Dif needs two extensions from the suspension engine:
%
% First, it needs
% for the engine to be careful when binding two suspended
% variables. Basically, in this case the engine must be sure to wake
% up one of the goals, as they may make dif fail. The way the engine
% does so is by searching the list of suspended variables, and search
% whether they share a common suspended goal. If they do, that
% suspended goal is added to the WokenList.
%
% Second, thanks to dif we may try to suspend on the same variable
% several times. dif calls a special version of freeze that checks
% whether that is in fact the case.
%
/** @pred dif( _X_, _Y_) /** @pred dif( _X_, _Y_)
@ -185,6 +149,42 @@ suspend if unification may still succeed or fail, and will fail if they
always unify. always unify.
Dif is tricky because we need to wake up on the two variables being
bound together, or on any variable of the term being bound to
another. Also, the day YAP fully supports infinite rational trees,
dif should work for them too. Hence, term comparison should not be
implemented in Prolog.
This is the way dif works. The '$can_unify' predicate does not know
anything about dif semantics, it just compares two terms for
equaility and is based on compare. If it succeeds without generating
a list of variables, the terms are equal and dif fails. If it fails,
dif succeeds.
If it succeeds but it creates a list of variables, dif creates
suspension records for all these variables on the '$redo_dif'(V,
X, Y) goal. V is a flag that says whether dif has completed or not,
X and Y are the original goals. Whenever one of these variables is
bound, it calls '$redo_dif' again. '$redo_dif' will then check whether V
was bound. If it was, dif has succeeded and redo_dif just
exits. Otherwise, '$redo_dif' will call dif again to see what happened.
Dif needs two extensions from the suspension engine:
First, it needs
for the engine to be careful when binding two suspended
variables. Basically, in this case the engine must be sure to wake
up one of the goals, as they may make dif fail. The way the engine
does so is by searching the list of suspended variables, and search
whether they share a common suspended goal. If they do, that
suspended goal is added to the WokenList.
Second, thanks to dif we may try to suspend on the same variable
several times. dif calls a special version of freeze that checks
whether that is in fact the case.
*/ */
prolog:dif(X, Y) :- prolog:dif(X, Y) :-
'$can_unify'(X, Y, LVars), !, '$can_unify'(X, Y, LVars), !,
@ -198,6 +198,7 @@ dif_suspend_on_lvars([H|T], G) :-
internal_freeze(H, G), internal_freeze(H, G),
dif_suspend_on_lvars(T, G). dif_suspend_on_lvars(T, G).
%% @pred redo_dif(_Done_, _X_, _Y_)
% %
% This predicate is called whenever a variable dif was suspended on is % This predicate is called whenever a variable dif was suspended on is
% bound. Note that dif may have already executed successfully. % bound. Note that dif may have already executed successfully.
@ -263,7 +264,7 @@ redo_ground('$done', _, Goal) :-
% %
% support for when/2 built-in % support for when/2 built-in
% %
/** @pred when(+ _C_,: _G_) /** @pred when(+ _C_, 0:_G_)
Delay execution of goal _G_ until the conditions _C_ are Delay execution of goal _G_ until the conditions _C_ are

View File

@ -6,7 +6,7 @@
/** /**
@ingroup ModuleBuiltins @addtogroup ModuleBuiltins
@{ @{
*/ */

View File

@ -4,11 +4,10 @@
/** @file preddyns.yap */ /** @file preddyns.yap */
/** /**
* @addtogroup Database * @addtogroup Internal_Database
* @{
*
* @brief main operations on dynamic predicates. * @brief main operations on dynamic predicates.
*
*
*/ */
/** @pred asserta(+ _C_) is iso /** @pred asserta(+ _C_) is iso

View File

@ -446,7 +446,7 @@ hide_predicate(P0) :-
nonvar(P), nonvar(P),
P = N/A, P = N/A,
!, !,
functor(S,N,A). functor(_S,N,A).
hide_predicate(P0) :- hide_predicate(P0) :-
strip_module(P0, M, P), strip_module(P0, M, P),
'$hide_predicate'(P, M). '$hide_predicate'(P, M).

View File

@ -362,7 +362,7 @@ available it tries reconsulting the source file.
qload_module(Mod) :- qload_module(Mod) :-
prolog_flag(verbose_load, OldF, false), prolog_flag(verbose_load, OldF, false),
prolog_flag(verbose, OldV, silent), prolog_flag(verbose, OldV, silent),
Verbosity = silent Verbosity = silent,
StartMsg = loading_module, StartMsg = loading_module,
EndMsg = module_loaded, EndMsg = module_loaded,
'$current_module'(SourceModule, Mod), '$current_module'(SourceModule, Mod),

View File

@ -34,20 +34,21 @@
setof/3], []). setof/3], []).
/** /**
*
@defgroup Sets Collecting Solutions to a Goal * @defgroup Sets Collecting Solutions to a Goal
@ingroup builtins * @ingroup builtins
@{ * @{
*
When there are several solutions to a goal, if the user wants to collect all *
the solutions he may be led to use the data base, because backtracking will * When there are several solutions to a goal, if the user wants to collect all
forget previous solutions. * the solutions he may be led to use the data base, because backtracking will
* forget previous solutions.
YAP allows the programmer to choose from several system *
predicates instead of writing his own routines. findall/3 gives you * YAP allows the programmer to choose from several system
the fastest, but crudest solution. The other built-in predicates * predicates instead of writing his own routines. findall/3 gives you
post-process the result of the query in several different ways: * the fastest, but crudest solution. The other built-in predicates
* post-process the result of the query in several different ways:
*
*/ */
:- use_system_module( '$_boot', ['$catch'/3]). :- use_system_module( '$_boot', ['$catch'/3]).

View File

@ -7,8 +7,11 @@
* *
* @addtogroup TopLevel Top-Level and Boot Predicates * @addtogroup TopLevel Top-Level and Boot Predicates
* @ingroup YAPControl * @ingroup YAPControl
* @{ *
*/ * [TOC]
*
* @{
* \*/
:- '$system_meta_predicates'([ :- '$system_meta_predicates'([
catch(0,?,0), catch(0,?,0),
@ -923,7 +926,7 @@ expand_term(Term,Expanded) :-
%% @} %% @}
%% @addto group YAPControl %% @addtogroup YAPControl
%% @{ %% @{