Merge branch 'master' of github.com:vscosta/yap-6.3
This commit is contained in:
commit
868961ebb5
@ -427,6 +427,8 @@ ructions *
|
||||
|
||||
Op(deallocate, p);
|
||||
CACHE_Y_AS_ENV(YREG);
|
||||
// do this before checking
|
||||
SREG = YREG;
|
||||
check_trail(TR);
|
||||
#ifndef NO_CHECKING
|
||||
/* check stacks */
|
||||
@ -435,7 +437,6 @@ ructions *
|
||||
PREG = NEXTOP(PREG, p);
|
||||
/* other instructions do depend on S being set by deallocate
|
||||
:-( */
|
||||
SREG = YREG;
|
||||
CPREG = (yamop *) ENV_YREG[E_CP];
|
||||
ENV = ENV_YREG = (CELL *) ENV_YREG[E_E];
|
||||
#ifdef DEPTH_LIMIT
|
||||
|
158
C/dbase.c
158
C/dbase.c
@ -25,92 +25,88 @@ static char SccsId[] = "%W% %G%";
|
||||
*
|
||||
* @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 "attvar.h"
|
||||
#include "clause.h"
|
||||
|
@ -90,8 +90,8 @@ endforeach(i ${DOCS_EXCLUDE_})
|
||||
add_subdirectory(../packages/raptor/doc ${CMAKE_BINARY_DIR}/packages/raptor/doc)
|
||||
|
||||
SET(DOC_INPUT_FILES_
|
||||
${CMAKE_SOURCE_DIR}/pl
|
||||
${CMAKE_SOURCE_DIR}/docs/md
|
||||
${CMAKE_SOURCE_DIR}/pl
|
||||
${CMAKE_SOURCE_DIR}/CXX
|
||||
${CMAKE_SOURCE_DIR}/OPTYap
|
||||
${CMAKE_SOURCE_DIR}/C
|
||||
|
@ -20,4 +20,6 @@ notation will be used:
|
||||
|
||||
+ an argument with no preceding symbol can be used in both ways.
|
||||
|
||||
@{
|
||||
[TOC]
|
||||
|
||||
@}
|
||||
|
@ -127,8 +127,8 @@ The rest of this appendix describes exhaustively how to interface C to YAP.
|
||||
@}
|
||||
|
||||
@defgroup Manipulating_Terms Terms
|
||||
@{
|
||||
@ingroup ChYInterface
|
||||
@{
|
||||
|
||||
This section provides information about the primitives available to the C
|
||||
programmer for manipulating Prolog terms.
|
||||
@ -504,8 +504,8 @@ code. Slots can also be used if there is small state.
|
||||
@}
|
||||
|
||||
@defgroup Unifying_Terms Unification
|
||||
@{
|
||||
@ingroup ChYInterface
|
||||
@{
|
||||
|
||||
YAP provides a single routine to attempt the unification of two Prolog
|
||||
terms. The routine may succeed or fail:
|
||||
@ -522,8 +522,8 @@ otherwise.
|
||||
@}
|
||||
|
||||
@defgroup CallYAP Using the compiler:
|
||||
@{
|
||||
@ingroup Manipulating_Strings Strings
|
||||
@{
|
||||
|
||||
|
||||
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
|
||||
@{
|
||||
@ingroup ChYInterface
|
||||
@{
|
||||
|
||||
|
||||
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`
|
||||
@{
|
||||
@ingroup ChYInterface
|
||||
@{
|
||||
|
||||
The C-Interface also provides the C-application with a measure of
|
||||
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
|
||||
@{
|
||||
@ingroup ChYInterface
|
||||
@{
|
||||
|
||||
The C-Interface provides the C-application with a a number of utility
|
||||
functions that are useful.
|
||||
@ -794,9 +794,8 @@ ignore the variable.
|
||||
@}
|
||||
|
||||
@defgroup Calling_YAP_From_C From `C` back to Prolog
|
||||
@{
|
||||
@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
|
||||
`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:
|
||||
@{
|
||||
@ingroup Module_Manipulation_in_C Module Manipulation in C
|
||||
@{
|
||||
|
||||
YAP allows one to create a new module from C-code. To create the new
|
||||
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
|
||||
@{
|
||||
@ingroup ChYInterface
|
||||
@{
|
||||
|
||||
<ul>
|
||||
<li>`void` YAP_Throw(`YAP_Term exception`)
|
||||
@ -1064,9 +1063,8 @@ of such arguments.
|
||||
@}
|
||||
|
||||
@defgroup Writing_C Writing predicates in C
|
||||
@{
|
||||
@ingroup ChYInterface
|
||||
### Writing predicates in C {#Writing_C}
|
||||
@{
|
||||
|
||||
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
|
||||
@{
|
||||
@ingroup ChYInterface
|
||||
@{
|
||||
|
||||
YAP4 includes several changes over the previous `load_foreign_files/3`
|
||||
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
|
||||
@{
|
||||
@ingroup ChYInterface
|
||||
@{
|
||||
|
||||
YAP can be used as a library to be called from other
|
||||
programs. To do so, you must first create the YAP library:
|
||||
|
@ -6,4 +6,6 @@
|
||||
`LIBDIR` variable in the Makefile for YAP). Several files in the
|
||||
library are originally from the public-domain Edinburgh Prolog library.
|
||||
|
||||
[TOC]
|
||||
|
||||
@}
|
||||
|
@ -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
|
||||
implemented as if by:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.prolog}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.yap}
|
||||
use_module(F) :-
|
||||
load_files(F, [if(not_loaded),must_be_module(true)]).
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -775,6 +775,9 @@ rhs(log(RHS), Logs ) :- !,
|
||||
rhs(exp(RHS), Logs ) :- !,
|
||||
rhs(RHS, X1),
|
||||
matrix_to_exps( X1, Logs ).
|
||||
rhs(sum(RHS), Logs ) :- !,
|
||||
rhs(RHS, X1),
|
||||
matrix_sum( X1, Logs ).
|
||||
rhs(S, NS) :-
|
||||
rhs_opaque( S ), !,
|
||||
S = NS.
|
||||
|
@ -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.
|
||||
|
||||
*/
|
||||
directory_map(D, P),
|
||||
directory_map(D, P) :-
|
||||
working_directory(_, D),
|
||||
list_directory(D,L),
|
||||
d_map(L, P).
|
||||
|
||||
d_map([],_,_,_).
|
||||
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) :-
|
||||
absolute_file_name( F, File, [prefix(D)] ),
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -832,10 +832,7 @@ gradient_descent :-
|
||||
forall(tunable_fact(FactID,GroundTruth),
|
||||
(XZ is 0.0, X[FactID] <== XZ,sigmoid(XZ,Slope,Pr),set_fact_probability(FactID,Pr))),
|
||||
problog_flag(sigmoid_slope,Slope),
|
||||
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_run(Solver,_BestF),
|
||||
lbfgs_finalize(Solver).
|
||||
|
||||
set_tunable(I,Slope,P) :-
|
||||
@ -848,38 +845,42 @@ set_tunable(I,Slope,P) :-
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
user:evaluate(LLH_Training_Queries, X,Grad,N,_,_) :-
|
||||
%Handle = user_error,
|
||||
GradCount <== array[N] of ints,
|
||||
example_count(TrainingExampleCount),
|
||||
LLs <== array[TrainingExampleCount ] of floats,
|
||||
Probs <== array[N] of floats,
|
||||
problog_flag(sigmoid_slope,Slope),
|
||||
N1 is N-1,
|
||||
|
||||
N1 is N-1,
|
||||
forall(between(0,N1,I),
|
||||
(Grad[I] <== 0.0, S <== X[I], sigmoid(S,Slope, P), Probs[I] <== P)
|
||||
),
|
||||
findall(LL,
|
||||
compute_grad(Grad, GradCount, Probs, Slope, LL),
|
||||
LLs
|
||||
),
|
||||
sum_list(LLs,LLH_Training_Queries).
|
||||
(Grad[I] <== 0.0, S <== X[I], sigmoid(S,Slope, P), Probs[I] <== P)
|
||||
), nl,
|
||||
forall(
|
||||
full_example(QueryID,QueryProb,BDD),
|
||||
compute_grad(QueryID, BDD, QueryProb,Grad, Probs, Slope,LLs)
|
||||
),
|
||||
LLH_Training_Queries <== sum(LLs),
|
||||
writeln(LLH_Training_Queries).
|
||||
%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) :-
|
||||
user:example(QueryID,_Query,QueryProb,_),
|
||||
recorded(QueryID,BDD,_),
|
||||
BDD = bdd(_Dir, _GradTree, MapList),
|
||||
MapList = [_|_],
|
||||
bind_maplist(MapList, Slope, Probs),
|
||||
%writeln( MapList ),
|
||||
compute_grad(QueryID,BDD,QueryProb, Grad, Probs, Slope, LLs) :-
|
||||
BDD = bdd(_Dir, _GradTree, MapList),
|
||||
bind_maplist(MapList, Slope, Probs),
|
||||
recorded(QueryID,BDD,_),
|
||||
qprobability(BDD,Slope,BDDProb),
|
||||
LL is (BDDProb-QueryProb)*(BDDProb-QueryProb),
|
||||
LLs[QueryID] <== LL,
|
||||
%writeln( qprobability(BDD,Slope,BDDProb) ),
|
||||
forall(
|
||||
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),
|
||||
% writeln(FactID),
|
||||
G0 <== Grad[FactID],
|
||||
@ -887,10 +888,7 @@ gradientpair(I, BDD,Slope,BDDProb, QueryProb, Grad, Probs, GradCount) :-
|
||||
%writeln( GN is G0-GradValue*(QueryProb-BDDProb)),
|
||||
GN is G0-GradValue*2*Prob*(1-Prob)*(QueryProb-BDDProb),
|
||||
%writeln(FactID:(G0->GN)),
|
||||
GC <== GradCount[FactID],
|
||||
GC1 is GC+1,
|
||||
GradCount[FactID] <== GC1,
|
||||
Grad[FactID] <== GN.
|
||||
Grad[FactID] <== GN.
|
||||
|
||||
qprobability(bdd(Dir, Tree, _MapList), Slope, Prob) :-
|
||||
/* 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) :-
|
||||
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),
|
||||
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]).
|
||||
|
@ -1,4 +1,4 @@
|
||||
set (PYTHON_SOURCES backcall/__init__.py
|
||||
set (PYTHON_SOURCES
|
||||
core/yap_kernel/__init__.py
|
||||
core/yap_kernel/getipython.py
|
||||
core/__init__.py
|
||||
@ -65,7 +65,6 @@ kernelspec.py
|
||||
__init__.py
|
||||
yap_kernel_launcher.py
|
||||
docs/conf.py
|
||||
backcall.py
|
||||
setup.py
|
||||
interactiveshell.py
|
||||
examples/embedding/internal_ipkernel.py
|
||||
@ -154,7 +153,6 @@ yap_ipython/core/logger.py
|
||||
yap_ipython/core/excolors.py
|
||||
yap_ipython/core/completer.py
|
||||
yap_ipython/core/ultratb.py
|
||||
yap_ipython/core/backcall.py
|
||||
yap_ipython/core/display.py
|
||||
yap_ipython/core/prompts.py
|
||||
yap_ipython/core/debugger.py
|
||||
|
@ -41,7 +41,7 @@ jupyter_cell(Caller, _, Line ) :-
|
||||
Query = Caller,
|
||||
catch(
|
||||
python_query(Query,Line),
|
||||
E=error(A,B),
|
||||
error(A,B),
|
||||
system_error(A,B)
|
||||
).
|
||||
|
||||
@ -69,7 +69,7 @@ jupyter_consult(Cell) :-
|
||||
open_mem_read_stream( Cell, Stream),
|
||||
load_files(user:'jupyter cell',[stream(Stream)| Options])
|
||||
),
|
||||
E=error(A,B),
|
||||
error(A,B),
|
||||
(close(Stream), system_error(A,B))
|
||||
),
|
||||
fail.
|
||||
|
@ -23,7 +23,7 @@
|
||||
jupyter( []).
|
||||
|
||||
ready( Engine, Query) :-
|
||||
errors( Engine , Cell ),
|
||||
errors( Engine , Query ),
|
||||
Es := Engine.errors,
|
||||
not Es == [].
|
||||
|
||||
@ -50,11 +50,11 @@ open_esh(Engine , Text, Stream, Name) :-
|
||||
Name := Engine.stream_name,
|
||||
open_mem_read_stream( Text, Stream ).
|
||||
|
||||
esh(Engine , Name, Stream) :-
|
||||
esh(Engine , _Name, Stream) :-
|
||||
repeat,
|
||||
catch(
|
||||
read_clause(Stream, Cl, [ syntax_errors(dec10)]),
|
||||
error(C,E),
|
||||
read_clause(Stream, Cl, [ syntax_errors(dec10)]),
|
||||
error(C,E),
|
||||
p3_message(C,Engine,E)
|
||||
),
|
||||
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))) :-
|
||||
python_clear_errors,
|
||||
!,
|
||||
Engine.errors := [t(Cause,LN,CharPos,Details)]+Engine.errors.
|
||||
p3_message(error, Engine, E) :-
|
||||
python_clear_errors,
|
||||
!,
|
||||
Engine.errors := [t(Cause,LN,CharPos,Details)]+Engine.errors .
|
||||
p3_message(error, _Engine, _E) :-
|
||||
python_clear_errors,
|
||||
!.
|
||||
p3_message(warning, Engine, E) :-
|
||||
!.
|
||||
p3_message(error, Engine, E) :-
|
||||
Engine.errors := [E] + Engine.errors.
|
||||
p3_message(warning, Engine, E) :-
|
||||
Engine.errors := [E] + Engine.errors.
|
||||
%% ready(_Self, Line ) :-
|
||||
p3_message(warning, _Engine, _E) :-
|
||||
!.
|
||||
p3_message(error, Engine, E) :-
|
||||
Engine.errors := [E] + Engine.errors.
|
||||
p3_message(warning, Engine, E) :-
|
||||
Engine.errors := [E] + Engine.errors.
|
||||
%% ready(_Self, Line ) :-
|
||||
%% blank( Line ),
|
||||
%% !.
|
||||
%% ready(Self, Line ) :-
|
||||
|
@ -3,20 +3,19 @@ import sys
|
||||
|
||||
from yap_ipython.core.debugger import Pdb
|
||||
|
||||
from yap_ipython.yapi import YAPCompleter
|
||||
#from .ptutils import IPythonPTCompleter
|
||||
from yap_ipython.core.completer import IPCompleter
|
||||
from .ptutils import IPythonPTCompleter
|
||||
from .shortcuts import suspend_to_bg, cursor_in_leading_ws
|
||||
|
||||
from prompt_toolkit.enums import DEFAULT_BUFFER
|
||||
from prompt_toolkit.filters import (Condition, HasFocus, HasSelection,
|
||||
ViInsertMode, EmacsInsertMode)
|
||||
from prompt_toolkit.keys import Keys
|
||||
from prompt_toolkit.key_binding.manager import KeyBindingManager
|
||||
from prompt_toolkit.filters import (Condition, has_focus, has_selection,
|
||||
vi_insert_mode, emacs_insert_mode)
|
||||
from prompt_toolkit.key_binding import KeyBindings
|
||||
from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline
|
||||
from prompt_toolkit.token import Token
|
||||
from prompt_toolkit.shortcuts import create_prompt_application
|
||||
from prompt_toolkit.interface import CommandLineInterface
|
||||
from pygments.token import Token
|
||||
from prompt_toolkit.shortcuts.prompt import PromptSession
|
||||
from prompt_toolkit.enums import EditingMode
|
||||
from prompt_toolkit.formatted_text import PygmentsTokens
|
||||
|
||||
|
||||
class TerminalPdb(Pdb):
|
||||
@ -26,46 +25,40 @@ class TerminalPdb(Pdb):
|
||||
self.pt_init()
|
||||
|
||||
def pt_init(self):
|
||||
def get_prompt_tokens(cli):
|
||||
def get_prompt_tokens():
|
||||
return [(Token.Prompt, self.prompt)]
|
||||
|
||||
def patch_stdout(**kwargs):
|
||||
return self.pt_cli.patch_stdout_context(**kwargs)
|
||||
|
||||
if self._ptcomp is None:
|
||||
compl = IPCompleter(shell=self.shell,
|
||||
namespace={},
|
||||
global_namespace={},
|
||||
parent=self.shell,
|
||||
)
|
||||
self._ptcomp = IPythonPTCompleter(compl, patch_stdout=patch_stdout)
|
||||
self._ptcomp = IPythonPTCompleter(compl)
|
||||
|
||||
kbmanager = KeyBindingManager.for_prompt()
|
||||
supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP'))
|
||||
kbmanager.registry.add_binding(Keys.ControlZ, filter=supports_suspend
|
||||
)(suspend_to_bg)
|
||||
kb = KeyBindings()
|
||||
supports_suspend = Condition(lambda: hasattr(signal, 'SIGTSTP'))
|
||||
kb.add('c-z', filter=supports_suspend)(suspend_to_bg)
|
||||
|
||||
if self.shell.display_completions == 'readlinelike':
|
||||
kbmanager.registry.add_binding(Keys.ControlI,
|
||||
filter=(HasFocus(DEFAULT_BUFFER)
|
||||
& ~HasSelection()
|
||||
& ViInsertMode() | EmacsInsertMode()
|
||||
& ~cursor_in_leading_ws
|
||||
))(display_completions_like_readline)
|
||||
multicolumn = (self.shell.display_completions == 'multicolumn')
|
||||
kb.add('tab', filter=(has_focus(DEFAULT_BUFFER)
|
||||
& ~has_selection
|
||||
& vi_insert_mode | emacs_insert_mode
|
||||
& ~cursor_in_leading_ws
|
||||
))(display_completions_like_readline)
|
||||
|
||||
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()),
|
||||
key_bindings_registry=kbmanager.registry,
|
||||
key_bindings=kb,
|
||||
history=self.shell.debugger_history,
|
||||
completer= self._ptcomp,
|
||||
completer=self._ptcomp,
|
||||
enable_history_search=True,
|
||||
mouse_support=self.shell.mouse_support,
|
||||
get_prompt_tokens=get_prompt_tokens,
|
||||
display_completions_in_columns=multicolumn,
|
||||
style=self.shell.style
|
||||
complete_style=self.shell.pt_complete_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):
|
||||
"""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.global_namespace = self.curframe.f_globals
|
||||
try:
|
||||
line = self.pt_cli.run(reset_current_buffer=True).text
|
||||
line = self.pt_app.prompt() # reset_current_buffer=True)
|
||||
except EOFError:
|
||||
line = 'EOF'
|
||||
line = self.precmd(line)
|
||||
|
@ -366,6 +366,9 @@ def embed(**kwargs):
|
||||
config = load_default_config()
|
||||
config.InteractiveShellEmbed = config.TerminalInteractiveShell
|
||||
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
|
||||
ps1 = None
|
||||
ps2 = None
|
||||
@ -383,7 +386,7 @@ def embed(**kwargs):
|
||||
shell = InteractiveShellEmbed.instance(_init_location_id='%s:%s' % (
|
||||
frame.f_code.co_filename, frame.f_lineno), **kwargs)
|
||||
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()
|
||||
#restore previous instance
|
||||
if saved_shell_instance is not None:
|
||||
|
@ -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 traitlets import (
|
||||
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.filters import (HasFocus, Condition, IsDone)
|
||||
from prompt_toolkit.formatted_text import PygmentsTokens
|
||||
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.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.style import Style
|
||||
@ -33,8 +34,8 @@ from .debugger import TerminalPdb, Pdb
|
||||
from .magics import TerminalMagics
|
||||
from .pt_inputhooks import get_inputhook_name_and_func
|
||||
from .prompts import Prompts, ClassicPrompts, RichPromptDisplayHook
|
||||
#from .ptutils import IPythonPTCompleter, IPythonPTLexer
|
||||
from .shortcuts import register_ipython_shortcuts
|
||||
from .ptutils import IPythonPTCompleter, IPythonPTLexer
|
||||
from .shortcuts import create_ipython_shortcuts
|
||||
|
||||
DISPLAY_BANNER_DEPRECATED = object()
|
||||
|
||||
@ -57,8 +58,6 @@ _style_overrides_linux = {
|
||||
Token.OutPromptNum: '#bb0000 bold',
|
||||
}
|
||||
|
||||
|
||||
|
||||
def get_default_editor():
|
||||
try:
|
||||
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):
|
||||
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)
|
||||
|
||||
def _space_for_menu_changed(self, old, new):
|
||||
self._update_layout()
|
||||
|
||||
pt_cli = None
|
||||
pt_app = None
|
||||
debugger_history = None
|
||||
_pt_app = None
|
||||
|
||||
simple_prompt = Bool(_use_simple_prompt,
|
||||
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`."""
|
||||
).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('colors')
|
||||
@ -169,9 +181,9 @@ class TerminalInteractiveShell(InteractiveShell):
|
||||
def _prompts_default(self):
|
||||
return self.prompts_class(self)
|
||||
|
||||
@observe('prompts')
|
||||
def _(self, change):
|
||||
self._update_layout()
|
||||
# @observe('prompts')
|
||||
# def _(self, change):
|
||||
# self._update_layout()
|
||||
|
||||
@default('displayhook_class')
|
||||
def _displayhook_class_default(self):
|
||||
@ -208,6 +220,10 @@ class TerminalInteractiveShell(InteractiveShell):
|
||||
"may be changed or removed in later releases."
|
||||
).tag(config=True)
|
||||
|
||||
enable_history_search = Bool(True,
|
||||
help="Allows to enable/disable the prompt toolkit history search"
|
||||
).tag(config=True)
|
||||
|
||||
@observe('term_title')
|
||||
def init_term_title(self, change=None):
|
||||
# Enable or disable the terminal title.
|
||||
@ -227,24 +243,19 @@ class TerminalInteractiveShell(InteractiveShell):
|
||||
def init_prompt_toolkit_cli(self):
|
||||
if self.simple_prompt:
|
||||
# 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():
|
||||
isp = self.input_splitter
|
||||
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())
|
||||
while isp.push_accepts_more():
|
||||
line = input(prompt_text)
|
||||
isp.push(line)
|
||||
prompt_text = prompt_continuation
|
||||
return isp.source_reset()
|
||||
while self.check_complete('\n'.join(lines))[0] == 'incomplete':
|
||||
lines.append( input(prompt_continuation) )
|
||||
return '\n'.join(lines)
|
||||
self.prompt_for_code = prompt
|
||||
return
|
||||
|
||||
# Set up keyboard shortcuts
|
||||
kbmanager = KeyBindingManager.for_prompt(
|
||||
enable_open_in_editor=self.extra_open_editor_shortcuts,
|
||||
)
|
||||
register_ipython_shortcuts(kbmanager.registry, self)
|
||||
key_bindings = create_ipython_shortcuts(self)
|
||||
|
||||
# Pre-populate history from yap_ipython's history database
|
||||
history = InMemoryHistory()
|
||||
@ -254,7 +265,7 @@ class TerminalInteractiveShell(InteractiveShell):
|
||||
# Ignore blank lines and consecutive duplicates
|
||||
cell = cell.rstrip()
|
||||
if cell and (cell != last_cell):
|
||||
history.append(cell)
|
||||
history.append_string(cell)
|
||||
last_cell = cell
|
||||
|
||||
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())
|
||||
|
||||
def patch_stdout(**kwargs):
|
||||
return self.pt_cli.patch_stdout_context(**kwargs)
|
||||
|
||||
self._pt_app = create_prompt_application(
|
||||
self.pt_app = PromptSession(
|
||||
editing_mode=editing_mode,
|
||||
key_bindings_registry=kbmanager.registry,
|
||||
key_bindings=key_bindings,
|
||||
history=history,
|
||||
# completer=IPythonPTCompleter(shell=self,
|
||||
# patch_stdout=patch_stdout),
|
||||
enable_history_search=True,
|
||||
completer=IPythonPTCompleter(shell=self),
|
||||
enable_history_search = self.enable_history_search,
|
||||
style=self.style,
|
||||
include_default_pygments_style=False,
|
||||
mouse_support=self.mouse_support,
|
||||
**self._layout_options()
|
||||
)
|
||||
self._eventloop = create_eventloop(self.inputhook)
|
||||
self.pt_cli = CommandLineInterface(
|
||||
self._pt_app, eventloop=self._eventloop,
|
||||
output=create_output(true_color=self.true_color))
|
||||
enable_open_in_editor=self.extra_open_editor_shortcuts,
|
||||
color_depth=(ColorDepth.TRUE_COLOR if self.true_color else None),
|
||||
**self._extra_prompt_options())
|
||||
|
||||
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.Namespace: 'bold #2080D0',
|
||||
Token.Prompt: '#009900',
|
||||
Token.PromptNum: '#00ff00 bold',
|
||||
Token.PromptNum: '#ansibrightgreen bold',
|
||||
Token.OutPrompt: '#990000',
|
||||
Token.OutPromptNum: '#ff0000 bold',
|
||||
Token.OutPromptNum: '#ansibrightred bold',
|
||||
})
|
||||
|
||||
# Hack: Due to limited color support on the Windows console
|
||||
@ -335,49 +340,66 @@ class TerminalInteractiveShell(InteractiveShell):
|
||||
style_cls = name_or_cls
|
||||
style_overrides = {
|
||||
Token.Prompt: '#009900',
|
||||
Token.PromptNum: '#00ff00 bold',
|
||||
Token.PromptNum: '#ansibrightgreen bold',
|
||||
Token.OutPrompt: '#990000',
|
||||
Token.OutPromptNum: '#ff0000 bold',
|
||||
Token.OutPromptNum: '#ansibrightred bold',
|
||||
}
|
||||
style_overrides.update(self.highlighting_style_overrides)
|
||||
style = PygmentsStyle.from_defaults(pygments_style_cls=style_cls,
|
||||
style_dict=style_overrides)
|
||||
style = merge_styles([
|
||||
style_from_pygments_cls(style_cls),
|
||||
style_from_pygments_dict(style_overrides),
|
||||
])
|
||||
|
||||
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
|
||||
"""
|
||||
def get_message():
|
||||
return PygmentsTokens(self.prompts.in_prompt_tokens())
|
||||
|
||||
return {
|
||||
'complete_in_thread': False,
|
||||
'lexer':IPythonPTLexer(),
|
||||
'reserve_space_for_menu':self.space_for_menu,
|
||||
'get_prompt_tokens':self.prompts.in_prompt_tokens,
|
||||
'get_continuation_tokens':self.prompts.continuation_prompt_tokens,
|
||||
'multiline':True,
|
||||
'display_completions_in_columns': (self.display_completions == 'multicolumn'),
|
||||
'message': get_message,
|
||||
'prompt_continuation': (
|
||||
lambda width, lineno, is_soft_wrap:
|
||||
PygmentsTokens(self.prompts.continuation_prompt_tokens(width))),
|
||||
'multiline': True,
|
||||
'complete_style': self.pt_complete_style,
|
||||
|
||||
# Highlight matching brackets, but only when this setting is
|
||||
# enabled, and only when the DEFAULT_BUFFER has the focus.
|
||||
'extra_input_processors': [ConditionalProcessor(
|
||||
'input_processors': [ConditionalProcessor(
|
||||
processor=HighlightMatchingBracketProcessor(chars='[](){}'),
|
||||
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):
|
||||
with self.pt_cli.patch_stdout_context(raw=True):
|
||||
document = self.pt_cli.run(
|
||||
pre_run=self.pre_prompt, reset_current_buffer=True)
|
||||
return document.text
|
||||
if self.rl_next_input:
|
||||
default = self.rl_next_input
|
||||
self.rl_next_input = None
|
||||
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):
|
||||
if sys.version_info >= (3, 6):
|
||||
@ -437,22 +459,6 @@ class TerminalInteractiveShell(InteractiveShell):
|
||||
|
||||
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):
|
||||
|
||||
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
|
||||
# out of our internal code.
|
||||
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:
|
||||
try:
|
||||
self.interact()
|
||||
@ -515,8 +521,9 @@ class TerminalInteractiveShell(InteractiveShell):
|
||||
return
|
||||
|
||||
tokens = self.prompts.rewrite_prompt_tokens()
|
||||
if self.pt_cli:
|
||||
self.pt_cli.print_tokens(tokens)
|
||||
if self.pt_app:
|
||||
print_formatted_text(PygmentsTokens(tokens), end='',
|
||||
style=self.pt_app.app.style)
|
||||
print(cmd)
|
||||
else:
|
||||
prompt = ''.join(s for t, s in tokens)
|
||||
@ -531,7 +538,7 @@ class TerminalInteractiveShell(InteractiveShell):
|
||||
elif self._prompts_before:
|
||||
self.prompts = self._prompts_before
|
||||
self._prompts_before = None
|
||||
self._update_layout()
|
||||
# self._update_layout()
|
||||
|
||||
|
||||
InteractiveShellABC.register(TerminalInteractiveShell)
|
||||
|
36
packages/python/yap_kernel/yap_ipython/terminal/ipapp.py
Normal file → Executable file
36
packages/python/yap_kernel/yap_ipython/terminal/ipapp.py
Normal file → Executable file
@ -18,7 +18,7 @@ from traitlets.config.loader import Config
|
||||
from traitlets.config.application import boolean_flag, catch_config_error
|
||||
from yap_ipython.core import release
|
||||
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.formatters import PlainTextFormatter
|
||||
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",
|
||||
)
|
||||
|
||||
addflag('banner', 'TerminalIPythonApp.display_banner',
|
||||
addflag('banner', 'Terminalyap_ipythonApp.display_banner',
|
||||
"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
|
||||
frontend_flags['quick']=(
|
||||
{'TerminalIPythonApp' : {'quick' : True}},
|
||||
{'Terminalyap_ipythonApp' : {'quick' : True}},
|
||||
"Enable quick startup with no config files."
|
||||
)
|
||||
|
||||
frontend_flags['i'] = (
|
||||
{'TerminalIPythonApp' : {'force_interact' : True}},
|
||||
{'Terminalyap_ipythonApp' : {'force_interact' : True}},
|
||||
"""If running code from the command line, become interactive afterwards.
|
||||
It is often useful to follow this with `--` to treat remaining flags as
|
||||
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"""
|
||||
subcommands = dict(
|
||||
profile=('yap_ipython.core.profileapp.ProfileLocate',
|
||||
@ -176,8 +176,8 @@ class LocateIPythonApp(BaseYAPApplication):
|
||||
print(self.ipython_dir)
|
||||
|
||||
|
||||
class TerminalIPythonApp(BaseYAPApplication, InteractiveShellApp):
|
||||
name = u'yap'
|
||||
class Terminalyap_ipythonApp(BaseYAPApplication, InteractiveShellApp):
|
||||
name = u'ipython'
|
||||
description = usage.cl_usage
|
||||
crash_handler_class = IPAppCrashHandler
|
||||
examples = _examples
|
||||
@ -194,7 +194,7 @@ class TerminalIPythonApp(BaseYAPApplication, InteractiveShellApp):
|
||||
|
||||
@default('classes')
|
||||
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 [
|
||||
InteractiveShellApp, # ShellApp comes before TerminalApp, because
|
||||
self.__class__, # it will also affect subclasses (e.g. QtConsole)
|
||||
@ -202,7 +202,7 @@ class TerminalIPythonApp(BaseYAPApplication, InteractiveShellApp):
|
||||
HistoryManager,
|
||||
ProfileDir,
|
||||
PlainTextFormatter,
|
||||
YAPCompleter,
|
||||
IPCompleter,
|
||||
ScriptMagics,
|
||||
LoggingMagics,
|
||||
StoreMagics,
|
||||
@ -215,7 +215,7 @@ class TerminalIPythonApp(BaseYAPApplication, InteractiveShellApp):
|
||||
notebook=('notebook.notebookapp.NotebookApp',
|
||||
"""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."""
|
||||
),
|
||||
nbconvert=('nbconvert.nbconvertapp.NbConvertApp',
|
||||
@ -232,11 +232,11 @@ class TerminalIPythonApp(BaseYAPApplication, InteractiveShellApp):
|
||||
profile = ("yap_ipython.core.profileapp.ProfileApp",
|
||||
"Create and manage yap_ipython profiles."
|
||||
),
|
||||
kernel = ("yap_kernel.kernelapp.YAPKernelApp",
|
||||
kernel = ("ipykernel.kernelapp.IPKernelApp",
|
||||
"Start a kernel without an attached frontend."
|
||||
),
|
||||
locate=('yap_ipython.terminal.ipapp.LocateIPythonApp',
|
||||
LocateIPythonApp.description
|
||||
locate=('yap_ipython.terminal.ipapp.Locateyap_ipythonApp',
|
||||
Locateyap_ipythonApp.description
|
||||
),
|
||||
history=('yap_ipython.core.historyapp.HistoryApp',
|
||||
"Manage the yap_ipython history database."
|
||||
@ -300,12 +300,12 @@ class TerminalIPythonApp(BaseYAPApplication, InteractiveShellApp):
|
||||
" Use `--matplotlib <backend>` and import pylab manually.")
|
||||
argv[idx] = '--pylab'
|
||||
|
||||
return super(TerminalIPythonApp, self).parse_command_line(argv)
|
||||
|
||||
return super(Terminalyap_ipythonApp, self).parse_command_line(argv)
|
||||
|
||||
@catch_config_error
|
||||
def initialize(self, argv=None):
|
||||
"""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:
|
||||
# don't bother initializing further, starting subapp
|
||||
return
|
||||
@ -368,12 +368,12 @@ def load_default_config(ipython_dir=None):
|
||||
ipython_dir = get_ipython_dir()
|
||||
|
||||
profile_dir = os.path.join(ipython_dir, 'profile_default')
|
||||
app = TerminalIPythonApp()
|
||||
app = Terminalyap_ipythonApp()
|
||||
app.config_file_paths.append(profile_dir)
|
||||
app.load_config_file()
|
||||
return app.config
|
||||
|
||||
launch_new_instance = TerminalIPythonApp.launch_instance
|
||||
launch_new_instance = Terminalyap_ipythonApp.launch_instance
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -9,7 +9,6 @@ import os
|
||||
import sys
|
||||
|
||||
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.lib.clipboard import ClipboardEmpty
|
||||
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):
|
||||
def __init__(self, shell):
|
||||
super(TerminalMagics, self).__init__(shell)
|
||||
self.input_splitter = IPythonInputSplitter()
|
||||
|
||||
def store_or_execute(self, block, name):
|
||||
""" Execute a block, or store it in a variable, per the user's request.
|
||||
@ -82,8 +80,6 @@ class TerminalMagics(Magics):
|
||||
@line_magic
|
||||
def autoindent(self, parameter_s = ''):
|
||||
"""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()
|
||||
print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])
|
||||
|
||||
|
@ -5,23 +5,34 @@ import sys
|
||||
|
||||
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):
|
||||
def __init__(self, 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 [
|
||||
(Token.Prompt, self.vi_mode() ),
|
||||
(Token.Prompt, 'In ['),
|
||||
(Token.PromptNum, str(self.shell.execution_count)),
|
||||
(Token.Prompt, ']: '),
|
||||
]
|
||||
|
||||
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:
|
||||
width = self._width()
|
||||
return [
|
||||
@ -42,12 +53,12 @@ class Prompts(object):
|
||||
]
|
||||
|
||||
class ClassicPrompts(Prompts):
|
||||
def in_prompt_tokens(self, cli=None):
|
||||
def in_prompt_tokens(self):
|
||||
return [
|
||||
(Token.Prompt, '>>> '),
|
||||
]
|
||||
|
||||
def continuation_prompt_tokens(self, cli=None, width=None):
|
||||
def continuation_prompt_tokens(self, width=None):
|
||||
return [
|
||||
(Token.Prompt, '... ')
|
||||
]
|
||||
@ -73,7 +84,9 @@ class RichPromptDisplayHook(DisplayHook):
|
||||
# Ask for a newline before multiline output
|
||||
self.prompt_end_newline = False
|
||||
|
||||
if self.shell.pt_cli:
|
||||
self.shell.pt_cli.print_tokens(tokens)
|
||||
if self.shell.pt_app:
|
||||
print_formatted_text(PygmentsTokens(tokens),
|
||||
style=self.shell.pt_app.app.style, end='',
|
||||
)
|
||||
else:
|
||||
sys.stdout.write(prompt_txt)
|
||||
|
@ -45,5 +45,5 @@ def get_inputhook_name_and_func(gui):
|
||||
os.environ['QT_API'] = 'pyqt5'
|
||||
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
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
|
||||
# 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
|
||||
# and never returned (there is not even a function to exit he
|
||||
# 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
|
||||
# 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
|
||||
# via yap_ipython options system.
|
||||
# via IPython options system.
|
||||
|
||||
import sys
|
||||
import time
|
||||
@ -26,11 +26,11 @@ import OpenGL.platform as platform
|
||||
from timeit import default_timer as clock
|
||||
|
||||
# Frame per second : 60
|
||||
# Should probably be an yap_ipython option
|
||||
# Should probably be an IPython option
|
||||
glut_fps = 60
|
||||
|
||||
# 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.GLUT_RGBA |
|
||||
glut.GLUT_DEPTH)
|
||||
@ -99,7 +99,7 @@ def inputhook(context):
|
||||
needed, otherwise, CPU usage is at 100%. 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.
|
||||
|
||||
signal.signal(signal.SIGINT, glut_int_handler)
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Enable pyglet to be used interacively with prompt_toolkit
|
||||
"""Enable pyglet to be used interactively with prompt_toolkit
|
||||
"""
|
||||
|
||||
import sys
|
||||
@ -29,7 +29,7 @@ def inputhook(context):
|
||||
needed, otherwise, CPU usage is at 100%. 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.
|
||||
try:
|
||||
t = clock()
|
||||
|
@ -1,15 +1,29 @@
|
||||
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
|
||||
# garbage collected.
|
||||
_appref = None
|
||||
|
||||
_already_warned = False
|
||||
|
||||
def inputhook(context):
|
||||
global _appref
|
||||
app = QtCore.QCoreApplication.instance()
|
||||
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([" "])
|
||||
event_loop = QtCore.QEventLoop(app)
|
||||
|
||||
|
@ -90,7 +90,7 @@ def inputhook_wx3(context):
|
||||
time.sleep is inserted. This is needed, otherwise, CPU usage is at 100%.
|
||||
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.
|
||||
try:
|
||||
app = wx.GetApp()
|
||||
|
@ -1,8 +1,8 @@
|
||||
raise DeprecationWarning("""DEPRECATED:
|
||||
|
||||
After Popular request and decision from the BDFL:
|
||||
`yap_ipython.terminal.ptshell` has been moved back to `yap_ipython.terminal.interactiveshell`
|
||||
during the beta cycle (after yap_ipython 5.0.beta3) Sorry about that.
|
||||
`IPython.terminal.ptshell` has been moved back to `IPython.terminal.interactiveshell`
|
||||
during the beta cycle (after IPython 5.0.beta3) Sorry about that.
|
||||
|
||||
This file will be removed in 5.0 rc or final.
|
||||
""")
|
||||
|
@ -1,21 +1,22 @@
|
||||
"""prompt-toolkit utilities
|
||||
|
||||
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.
|
||||
|
||||
import unicodedata
|
||||
from wcwidth import wcwidth
|
||||
|
||||
from yap_ipython.core.completer import (
|
||||
from IPython.core.completer import (
|
||||
provisionalcompleter, cursor_to_position,
|
||||
_deduplicate_completions)
|
||||
from prompt_toolkit.completion import Completer, Completion
|
||||
from prompt_toolkit.layout.lexers import Lexer
|
||||
from prompt_toolkit.layout.lexers import PygmentsLexer
|
||||
from prompt_toolkit.lexers import Lexer
|
||||
from prompt_toolkit.lexers import PygmentsLexer
|
||||
from prompt_toolkit.patch_stdout import patch_stdout
|
||||
|
||||
import pygments.lexers as pygments_lexers
|
||||
|
||||
@ -51,15 +52,12 @@ def _adjust_completion_text_based_on_context(text, body, offset):
|
||||
|
||||
|
||||
class IPythonPTCompleter(Completer):
|
||||
"""Adaptor to provide yap_ipython completions to prompt_toolkit"""
|
||||
def __init__(self, ipy_completer=None, shell=None, patch_stdout=None):
|
||||
"""Adaptor to provide IPython completions to prompt_toolkit"""
|
||||
def __init__(self, ipy_completer=None, shell=None):
|
||||
if shell is None and ipy_completer is None:
|
||||
raise TypeError("Please pass shell=an InteractiveShell instance.")
|
||||
self._ipy_completer = ipy_completer
|
||||
self.shell = shell
|
||||
if patch_stdout is None:
|
||||
raise TypeError("Please pass patch_stdout")
|
||||
self.patch_stdout = patch_stdout
|
||||
|
||||
@property
|
||||
def ipy_completer(self):
|
||||
@ -75,7 +73,7 @@ class IPythonPTCompleter(Completer):
|
||||
# is imported). This context manager ensures that doesn't interfere with
|
||||
# the prompt.
|
||||
|
||||
with self.patch_stdout(), provisionalcompleter():
|
||||
with patch_stdout(), provisionalcompleter():
|
||||
body = document.text
|
||||
cursor_row = document.cursor_position_row
|
||||
cursor_col = document.cursor_position_col
|
||||
@ -143,7 +141,7 @@ class IPythonPTLexer(Lexer):
|
||||
'latex': PygmentsLexer(l.TexLexer),
|
||||
}
|
||||
|
||||
def lex_document(self, cli, document):
|
||||
def lex_document(self, document):
|
||||
text = document.text.lstrip()
|
||||
|
||||
lexer = self.python_lexer
|
||||
@ -157,4 +155,4 @@ class IPythonPTLexer(Lexer):
|
||||
lexer = l
|
||||
break
|
||||
|
||||
return lexer.lex_document(cli, document)
|
||||
return lexer.lex_document(document)
|
||||
|
@ -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`
|
||||
"""
|
||||
|
||||
# Copyright (c) yap_ipython Development Team.
|
||||
# Copyright (c) IPython Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import warnings
|
||||
@ -12,91 +12,78 @@ import sys
|
||||
from typing import Callable
|
||||
|
||||
|
||||
from prompt_toolkit.application.current import get_app
|
||||
from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER
|
||||
from prompt_toolkit.filters import (HasFocus, HasSelection, Condition,
|
||||
ViInsertMode, EmacsInsertMode, HasCompletions)
|
||||
from prompt_toolkit.filters.cli import ViMode, ViNavigationMode
|
||||
from prompt_toolkit.keys import Keys
|
||||
from prompt_toolkit.filters import (has_focus, has_selection, Condition,
|
||||
vi_insert_mode, emacs_insert_mode, has_completions, vi_mode)
|
||||
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
|
||||
@Condition
|
||||
def cursor_in_leading_ws(cli):
|
||||
before = cli.application.buffer.document.current_line_before_cursor
|
||||
def cursor_in_leading_ws():
|
||||
before = get_app().current_buffer.document.current_line_before_cursor
|
||||
return (not before) or before.isspace()
|
||||
|
||||
def register_ipython_shortcuts(registry, shell):
|
||||
"""Set up the prompt_toolkit keyboard shortcuts for yap_ipython"""
|
||||
insert_mode = ViInsertMode() | EmacsInsertMode()
|
||||
|
||||
def create_ipython_shortcuts(shell):
|
||||
"""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):
|
||||
return_handler = shell.handle_return(shell)
|
||||
else:
|
||||
return_handler = newline_or_execute_outer(shell)
|
||||
|
||||
# Ctrl+J == Enter, seemingly
|
||||
registry.add_binding(Keys.ControlJ,
|
||||
filter=(HasFocus(DEFAULT_BUFFER)
|
||||
& ~HasSelection()
|
||||
& insert_mode
|
||||
kb.add('enter', filter=(has_focus(DEFAULT_BUFFER)
|
||||
& ~has_selection
|
||||
& insert_mode
|
||||
))(return_handler)
|
||||
|
||||
registry.add_binding(Keys.ControlBackslash)(force_exit)
|
||||
kb.add('c-\\')(force_exit)
|
||||
|
||||
registry.add_binding(Keys.ControlP,
|
||||
filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER)
|
||||
))(previous_history_or_previous_completion)
|
||||
kb.add('c-p', filter=(vi_insert_mode & has_focus(DEFAULT_BUFFER))
|
||||
)(previous_history_or_previous_completion)
|
||||
|
||||
registry.add_binding(Keys.ControlN,
|
||||
filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER)
|
||||
))(next_history_or_next_completion)
|
||||
kb.add('c-n', filter=(vi_insert_mode & has_focus(DEFAULT_BUFFER))
|
||||
)(next_history_or_next_completion)
|
||||
|
||||
registry.add_binding(Keys.ControlG,
|
||||
filter=(HasFocus(DEFAULT_BUFFER) & HasCompletions()
|
||||
))(dismiss_completion)
|
||||
kb.add('c-g', filter=(has_focus(DEFAULT_BUFFER) & has_completions)
|
||||
)(dismiss_completion)
|
||||
|
||||
registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER)
|
||||
)(reset_buffer)
|
||||
kb.add('c-c', filter=has_focus(DEFAULT_BUFFER))(reset_buffer)
|
||||
|
||||
registry.add_binding(Keys.ControlC, filter=HasFocus(SEARCH_BUFFER)
|
||||
)(reset_search_buffer)
|
||||
kb.add('c-c', filter=has_focus(SEARCH_BUFFER))(reset_search_buffer)
|
||||
|
||||
supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP'))
|
||||
registry.add_binding(Keys.ControlZ, filter=supports_suspend
|
||||
)(suspend_to_bg)
|
||||
supports_suspend = Condition(lambda: hasattr(signal, 'SIGTSTP'))
|
||||
kb.add('c-z', filter=supports_suspend)(suspend_to_bg)
|
||||
|
||||
# Ctrl+I == Tab
|
||||
registry.add_binding(Keys.ControlI,
|
||||
filter=(HasFocus(DEFAULT_BUFFER)
|
||||
& ~HasSelection()
|
||||
& insert_mode
|
||||
& cursor_in_leading_ws
|
||||
kb.add('tab', filter=(has_focus(DEFAULT_BUFFER)
|
||||
& ~has_selection
|
||||
& insert_mode
|
||||
& cursor_in_leading_ws
|
||||
))(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,
|
||||
filter=(HasFocus(DEFAULT_BUFFER)
|
||||
& EmacsInsertMode()))(newline_autoindent_outer(shell.input_splitter))
|
||||
|
||||
registry.add_binding(Keys.F2,
|
||||
filter=HasFocus(DEFAULT_BUFFER)
|
||||
)(open_input_in_editor)
|
||||
kb.add('f2', filter=has_focus(DEFAULT_BUFFER))(open_input_in_editor)
|
||||
|
||||
if shell.display_completions == 'readlinelike':
|
||||
registry.add_binding(Keys.ControlI,
|
||||
filter=(HasFocus(DEFAULT_BUFFER)
|
||||
& ~HasSelection()
|
||||
& insert_mode
|
||||
& ~cursor_in_leading_ws
|
||||
))(display_completions_like_readline)
|
||||
kb.add('c-i', filter=(has_focus(DEFAULT_BUFFER)
|
||||
& ~has_selection
|
||||
& insert_mode
|
||||
& ~cursor_in_leading_ws
|
||||
))(display_completions_like_readline)
|
||||
|
||||
if sys.platform == 'win32':
|
||||
registry.add_binding(Keys.ControlV,
|
||||
filter=(
|
||||
HasFocus(
|
||||
DEFAULT_BUFFER) & ~ViMode()
|
||||
))(win_paste)
|
||||
kb.add('c-v', filter=(has_focus(DEFAULT_BUFFER) & ~vi_mode))(win_paste)
|
||||
|
||||
return kb
|
||||
|
||||
|
||||
def newline_or_execute_outer(shell):
|
||||
@ -119,18 +106,24 @@ def newline_or_execute_outer(shell):
|
||||
check_text = d.text
|
||||
else:
|
||||
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
|
||||
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
|
||||
|
||||
if (status != 'incomplete') and b.accept_action.is_returnable:
|
||||
b.accept_action.validate_and_handle(event.cli, b)
|
||||
if (status != 'incomplete') and b.accept_handler:
|
||||
b.validate_and_handle()
|
||||
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
|
||||
|
||||
|
||||
@ -170,10 +163,10 @@ def reset_search_buffer(event):
|
||||
if event.current_buffer.document.text:
|
||||
event.current_buffer.reset()
|
||||
else:
|
||||
event.cli.push_focus(DEFAULT_BUFFER)
|
||||
event.app.layout.focus(DEFAULT_BUFFER)
|
||||
|
||||
def suspend_to_bg(event):
|
||||
event.cli.suspend_to_background()
|
||||
event.app.suspend_to_background()
|
||||
|
||||
def force_exit(event):
|
||||
"""
|
||||
@ -187,14 +180,14 @@ def indent_buffer(event):
|
||||
@undoc
|
||||
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.
|
||||
|
||||
Preserve margin and cursor position when using
|
||||
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.",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
|
||||
@ -232,13 +225,13 @@ def newline_autoindent_outer(inputsplitter) -> Callable[..., None]:
|
||||
|
||||
|
||||
def open_input_in_editor(event):
|
||||
event.cli.current_buffer.tempfile_suffix = ".py"
|
||||
event.cli.current_buffer.open_in_editor(event.cli)
|
||||
event.app.current_buffer.tempfile_suffix = ".py"
|
||||
event.app.current_buffer.open_in_editor()
|
||||
|
||||
|
||||
if sys.platform == 'win32':
|
||||
from yap_ipython.core.error import TryNext
|
||||
from yap_ipython.lib.clipboard import (ClipboardEmpty,
|
||||
from IPython.core.error import TryNext
|
||||
from IPython.lib.clipboard import (ClipboardEmpty,
|
||||
win32_clipboard_get,
|
||||
tkinter_clipboard_get)
|
||||
|
||||
|
@ -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
|
||||
# the file COPYING, distributed as part of this software.
|
||||
@ -15,8 +15,8 @@ import os
|
||||
import subprocess
|
||||
import sys
|
||||
import nose.tools as nt
|
||||
from yap_ipython.utils.tempdir import NamedFileInTemporaryDirectory
|
||||
from yap_ipython.testing.decorators import skip_win32
|
||||
from IPython.utils.tempdir import NamedFileInTemporaryDirectory
|
||||
from IPython.testing.decorators import skip_win32
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Tests
|
||||
@ -24,13 +24,13 @@ from yap_ipython.testing.decorators import skip_win32
|
||||
|
||||
|
||||
_sample_embed = b"""
|
||||
import yap_ipython
|
||||
import IPython
|
||||
|
||||
a = 3
|
||||
b = 14
|
||||
print(a, '.', b)
|
||||
|
||||
yap_ipython.embed()
|
||||
IPython.embed()
|
||||
|
||||
print('bye!')
|
||||
"""
|
||||
@ -38,7 +38,7 @@ print('bye!')
|
||||
_exit = b"exit\r"
|
||||
|
||||
def test_ipython_embed():
|
||||
"""test that `yap_ipython.embed()` works"""
|
||||
"""test that `IPython.embed()` works"""
|
||||
with NamedFileInTemporaryDirectory('file_with_embed.py') as f:
|
||||
f.write(_sample_embed)
|
||||
f.flush()
|
||||
@ -58,26 +58,27 @@ def test_ipython_embed():
|
||||
nt.assert_in('3 . 14', std)
|
||||
if os.name != 'nt':
|
||||
# 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)
|
||||
|
||||
@skip_win32
|
||||
def test_nest_embed():
|
||||
"""test that `yap_ipython.embed()` is nestable"""
|
||||
"""test that `IPython.embed()` is nestable"""
|
||||
import pexpect
|
||||
ipy_prompt = r']:' #ansi color codes give problems matching beyond this
|
||||
env = os.environ.copy()
|
||||
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)
|
||||
child.timeout = 5
|
||||
child.expect(ipy_prompt)
|
||||
child.sendline("import yap_ipython")
|
||||
child.sendline("import IPython")
|
||||
child.expect(ipy_prompt)
|
||||
child.sendline("ip0 = get_ipython()")
|
||||
#enter first nested embed
|
||||
child.sendline("yap_ipython.embed()")
|
||||
child.sendline("IPython.embed()")
|
||||
#skip the banner until we get to a prompt
|
||||
try:
|
||||
prompted = -1
|
||||
@ -86,15 +87,16 @@ def test_nest_embed():
|
||||
except pexpect.TIMEOUT as e:
|
||||
print(e)
|
||||
#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')")
|
||||
assert(child.expect(['true\r\n', 'false\r\n']) == 0)
|
||||
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)
|
||||
child.expect(ipy_prompt)
|
||||
#enter second nested embed
|
||||
child.sendline("yap_ipython.embed()")
|
||||
child.sendline("IPython.embed()")
|
||||
#skip the banner until we get to a prompt
|
||||
try:
|
||||
prompted = -1
|
||||
@ -103,11 +105,12 @@ def test_nest_embed():
|
||||
except pexpect.TIMEOUT as e:
|
||||
print(e)
|
||||
#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')")
|
||||
assert(child.expect(['true\r\n', 'false\r\n']) == 0)
|
||||
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)
|
||||
child.expect(ipy_prompt)
|
||||
child.sendline('exit')
|
||||
@ -116,7 +119,7 @@ def test_nest_embed():
|
||||
child.sendline("print('true' if get_ipython() is embed1 else 'false')")
|
||||
assert(child.expect(['true\r\n', 'false\r\n']) == 0)
|
||||
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)
|
||||
child.expect(ipy_prompt)
|
||||
child.sendline('exit')
|
||||
@ -125,7 +128,7 @@ def test_nest_embed():
|
||||
child.sendline("print('true' if get_ipython() is ip0 else 'false')")
|
||||
assert(child.expect(['true\r\n', 'false\r\n']) == 0)
|
||||
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)
|
||||
child.expect(ipy_prompt)
|
||||
child.sendline('exit')
|
||||
|
@ -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.
|
||||
|
||||
import yap_ipython.testing.tools as tt
|
||||
import IPython.testing.tools as tt
|
||||
|
||||
|
||||
def test_ipython_help():
|
||||
|
@ -1,16 +1,16 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""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.
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from yap_ipython.core.inputtransformer import InputTransformer
|
||||
from yap_ipython.testing import tools as tt
|
||||
from yap_ipython.utils.capture import capture_output
|
||||
from IPython.core.inputtransformer import InputTransformer
|
||||
from IPython.testing import tools as tt
|
||||
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
|
||||
|
||||
class TestElide(unittest.TestCase):
|
||||
@ -67,7 +67,7 @@ class mock_input_helper(object):
|
||||
def mock_input(testfunc):
|
||||
"""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.
|
||||
"""
|
||||
def test_method(self):
|
||||
@ -96,9 +96,7 @@ class InteractiveShellTestCase(unittest.TestCase):
|
||||
@mock_input
|
||||
def test_inputtransformer_syntaxerror(self):
|
||||
ip = get_ipython()
|
||||
transformer = SyntaxErrorTransformer()
|
||||
ip.input_splitter.python_line_transforms.append(transformer)
|
||||
ip.input_transformer_manager.python_line_transforms.append(transformer)
|
||||
ip.input_transformers_post.append(syntax_error_transformer)
|
||||
|
||||
try:
|
||||
#raise Exception
|
||||
@ -112,8 +110,7 @@ class InteractiveShellTestCase(unittest.TestCase):
|
||||
yield u'print(4*4)'
|
||||
|
||||
finally:
|
||||
ip.input_splitter.python_line_transforms.remove(transformer)
|
||||
ip.input_transformer_manager.python_line_transforms.remove(transformer)
|
||||
ip.input_transformers_post.remove(syntax_error_transformer)
|
||||
|
||||
def test_plain_text_only(self):
|
||||
ip = get_ipython()
|
||||
@ -135,7 +132,7 @@ class InteractiveShellTestCase(unittest.TestCase):
|
||||
|
||||
class Test2(Test):
|
||||
def _ipython_display_(self):
|
||||
from yap_ipython.display import display
|
||||
from IPython.display import display
|
||||
display('<custom>')
|
||||
|
||||
# verify that _ipython_display_ shortcut isn't called
|
||||
@ -146,20 +143,17 @@ class InteractiveShellTestCase(unittest.TestCase):
|
||||
self.assertEqual(data, {'text/plain': repr(obj)})
|
||||
assert captured.stdout == ''
|
||||
|
||||
|
||||
|
||||
class SyntaxErrorTransformer(InputTransformer):
|
||||
def push(self, line):
|
||||
def syntax_error_transformer(lines):
|
||||
"""Transformer that throws SyntaxError if 'syntaxerror' is in the code."""
|
||||
for line in lines:
|
||||
pos = line.find('syntaxerror')
|
||||
if pos >= 0:
|
||||
e = SyntaxError('input contains "syntaxerror"')
|
||||
e.text = line
|
||||
e.offset = pos + 1
|
||||
raise e
|
||||
return line
|
||||
return lines
|
||||
|
||||
def reset(self):
|
||||
pass
|
||||
|
||||
class TerminalMagicsTestCase(unittest.TestCase):
|
||||
def test_paste_magics_blankline(self):
|
||||
|
@ -684,7 +684,7 @@ class YAPRun:
|
||||
for i in self.errors:
|
||||
try:
|
||||
(_,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
|
||||
except SyntaxError:
|
||||
self.shell.showsyntaxerror( )
|
||||
@ -723,7 +723,7 @@ class YAPRun:
|
||||
# Give the displayhook a reference to our ExecutionResult so it
|
||||
# can fill in the output value.
|
||||
self.shell.displayhook.exec_result = self.result
|
||||
if syntaxErrors(self, text):
|
||||
if self.syntaxErrors(cell):
|
||||
self.result.result = False
|
||||
has_raised = False
|
||||
try:
|
||||
@ -829,5 +829,5 @@ class YAPRun:
|
||||
(query, _,loop, sols) = self.clean_end(query)
|
||||
return (program, query, loop, sols)
|
||||
|
||||
global
|
||||
globals = {}
|
||||
# global
|
||||
#globals = {}
|
||||
|
@ -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.
|
||||
|
||||
~~~~
|
||||
?- lbfgs_parameters.
|
||||
?- lbfgs_parameters(State).
|
||||
==========================================================================================
|
||||
Type Name Value Description
|
||||
==========================================================================================
|
||||
|
@ -95,5 +95,5 @@ endif()
|
||||
|
||||
|
||||
install(FILES ${PL_BOOT_SOURCES}
|
||||
DESTINATION ${libpl}/pll
|
||||
DESTINATION ${libpl}/pl
|
||||
)
|
||||
|
@ -15,6 +15,10 @@
|
||||
* *
|
||||
*************************************************************************/
|
||||
|
||||
/**
|
||||
* @file checker.yap
|
||||
*
|
||||
*/
|
||||
:- system_module( style_checker, [no_style_check/1,
|
||||
style_check/1], ['$check_term'/5,
|
||||
'$sv_warning'/2,
|
||||
@ -24,7 +28,7 @@
|
||||
|
||||
/**
|
||||
|
||||
@defgroup YAPStyle Checker
|
||||
@defgroup YAPStyleChecker Style Checker
|
||||
@ingroup YAPCompilerSettings
|
||||
@{
|
||||
|
||||
@ -167,6 +171,6 @@ separated by clauses from other procedures.
|
||||
|
||||
discontiguous(P) :- '$discontiguous'(P).
|
||||
|
||||
/*
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
@ -101,6 +101,10 @@ files and to set-up the Prolog environment. We discuss
|
||||
|
||||
+ @ref YAPCompilerSettings
|
||||
|
||||
@}
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup YAPReadFiles The Predicates that Read Source Files
|
||||
@ingroup YAPConsulting
|
||||
|
||||
@ -1678,6 +1682,10 @@ End of conditional compilation.
|
||||
current_prolog_flag(source, true), !.
|
||||
'$fetch_comp_status'(compact).
|
||||
|
||||
/** consult_depth(-int:_LV_)
|
||||
*
|
||||
* Unify _LV_ with the number of files being consulted.
|
||||
*/
|
||||
consult_depth(LV) :- '$show_consult_level'(LV).
|
||||
|
||||
prolog_library(File) :-
|
||||
|
@ -41,7 +41,7 @@
|
||||
|
||||
|
||||
/**
|
||||
* @ingroup AttributedVariables_Builtins
|
||||
* @addtogroup AttributedVariables_Builtins
|
||||
* @{
|
||||
*
|
||||
*
|
||||
@ -141,42 +141,6 @@ freeze_goal(V,G) :-
|
||||
'$current_module'(M),
|
||||
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_)
|
||||
|
||||
|
||||
@ -185,6 +149,42 @@ suspend if unification may still succeed or fail, and will fail if they
|
||||
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) :-
|
||||
'$can_unify'(X, Y, LVars), !,
|
||||
@ -198,6 +198,7 @@ dif_suspend_on_lvars([H|T], G) :-
|
||||
internal_freeze(H, 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
|
||||
% bound. Note that dif may have already executed successfully.
|
||||
@ -263,7 +264,7 @@ redo_ground('$done', _, Goal) :-
|
||||
%
|
||||
% 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
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
/**
|
||||
|
||||
@ingroup ModuleBuiltins
|
||||
@addtogroup ModuleBuiltins
|
||||
@{
|
||||
*/
|
||||
|
||||
|
@ -4,11 +4,10 @@
|
||||
/** @file preddyns.yap */
|
||||
|
||||
/**
|
||||
* @addtogroup Database
|
||||
* @{
|
||||
*
|
||||
* @addtogroup Internal_Database
|
||||
* @brief main operations on dynamic predicates.
|
||||
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/** @pred asserta(+ _C_) is iso
|
||||
|
@ -446,7 +446,7 @@ hide_predicate(P0) :-
|
||||
nonvar(P),
|
||||
P = N/A,
|
||||
!,
|
||||
functor(S,N,A).
|
||||
functor(_S,N,A).
|
||||
hide_predicate(P0) :-
|
||||
strip_module(P0, M, P),
|
||||
'$hide_predicate'(P, M).
|
||||
|
@ -362,7 +362,7 @@ available it tries reconsulting the source file.
|
||||
qload_module(Mod) :-
|
||||
prolog_flag(verbose_load, OldF, false),
|
||||
prolog_flag(verbose, OldV, silent),
|
||||
Verbosity = silent
|
||||
Verbosity = silent,
|
||||
StartMsg = loading_module,
|
||||
EndMsg = module_loaded,
|
||||
'$current_module'(SourceModule, Mod),
|
||||
|
29
pl/setof.yap
29
pl/setof.yap
@ -34,20 +34,21 @@
|
||||
setof/3], []).
|
||||
|
||||
/**
|
||||
|
||||
@defgroup Sets Collecting Solutions to a Goal
|
||||
@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
|
||||
forget previous solutions.
|
||||
|
||||
YAP allows the programmer to choose from several system
|
||||
predicates instead of writing his own routines. findall/3 gives you
|
||||
the fastest, but crudest solution. The other built-in predicates
|
||||
post-process the result of the query in several different ways:
|
||||
|
||||
*
|
||||
* @defgroup Sets Collecting Solutions to a Goal
|
||||
* @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
|
||||
* forget previous solutions.
|
||||
*
|
||||
* YAP allows the programmer to choose from several system
|
||||
* predicates instead of writing his own routines. findall/3 gives you
|
||||
* 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]).
|
||||
|
@ -7,8 +7,11 @@
|
||||
*
|
||||
* @addtogroup TopLevel Top-Level and Boot Predicates
|
||||
* @ingroup YAPControl
|
||||
* @{
|
||||
*/
|
||||
*
|
||||
* [TOC]
|
||||
*
|
||||
* @{
|
||||
* \*/
|
||||
|
||||
:- '$system_meta_predicates'([
|
||||
catch(0,?,0),
|
||||
@ -923,7 +926,7 @@ expand_term(Term,Expanded) :-
|
||||
|
||||
%% @}
|
||||
|
||||
%% @addto group YAPControl
|
||||
%% @addtogroup YAPControl
|
||||
|
||||
%% @{
|
||||
|
||||
|
Reference in New Issue
Block a user