Merge branch 'master' of github.com:vscosta/yap-6.3
This commit is contained in:
commit
5d69b09688
68
C/gprof.c
68
C/gprof.c
@ -35,7 +35,7 @@
|
||||
* Revision 1.3 2006/01/17 14:10:40 vsc
|
||||
* YENV may be an HW register (breaks some tabling code)
|
||||
* All YAAM instructions are now brackedted, so Op introduced an { and EndOp introduces an }. This is because Ricardo assumes that.
|
||||
* Fix attvars when COROUTING is undefined.
|
||||
* Fix attvars
|
||||
*
|
||||
* Revision 1.2 2005/12/23 00:20:13 vsc
|
||||
* updates to gprof
|
||||
@ -47,39 +47,39 @@
|
||||
* *
|
||||
*************************************************************************/
|
||||
|
||||
/// @file gprof.c
|
||||
|
||||
/** @defgroup Tick_Profiler Tick Profiler
|
||||
@ingroup Profiling
|
||||
@{
|
||||
|
||||
The tick profiler works by interrupting the Prolog code every so often
|
||||
and checking at each point the code was. The profiler must be able to
|
||||
retrace the state of the abstract machine at every moment. The major
|
||||
advantage of this approach is that it gives the actual amount of time
|
||||
being spent per procedure, or whether garbage collection dominates
|
||||
execution time. The major drawback is that tracking down the state of
|
||||
the abstract machine may take significant time, and in the worst case
|
||||
may slow down the whole execution.
|
||||
|
||||
The following procedures are available:
|
||||
|
||||
+ profinit
|
||||
|
||||
|
||||
Initialise the data-structures for the profiler. Unnecessary for
|
||||
dynamic profiler.
|
||||
|
||||
+ profon
|
||||
|
||||
|
||||
Start profiling.
|
||||
|
||||
+ profoff
|
||||
|
||||
|
||||
Stop profiling.
|
||||
|
||||
|
||||
/** @addtogroup Tick_Profiler
|
||||
* @ingroup Profiling@{
|
||||
*
|
||||
* The tick profiler works by interrupting the Prolog code every so often
|
||||
* and checking at each point the code was. The pro/filer must be able to
|
||||
* retrace the state of the abstract machine at every moment. The major
|
||||
* advantage of this approach is that it gives the actual amount of time
|
||||
* being spent per procedure, or whether garbage collection dominates
|
||||
* execution time. The major drawback is that tracking down the state of
|
||||
* the abstract machine may take significant time, and in the worst case
|
||||
* may slow down the whole execution.
|
||||
*
|
||||
* The following procedures are available:
|
||||
*
|
||||
* + profinit/0
|
||||
* Initialise the data-structures for the profiler. Unnecessary for
|
||||
* dynamic profiler.
|
||||
*
|
||||
* + profon/0
|
||||
* Start profiling.
|
||||
*
|
||||
* + profoff/0
|
||||
* Stop profiling.
|
||||
*
|
||||
* + profoff/0
|
||||
* Stop profiling.
|
||||
*
|
||||
* + showprofres/0 and showprofres/1
|
||||
* Stop tick counts per predicate.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef SCCS
|
||||
@ -841,7 +841,7 @@ static void RemoveCode(CODEADDR clau)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
static Int
|
||||
showprofres( USES_REGS1 ) {
|
||||
buf_ptr buf;
|
||||
|
||||
|
@ -767,6 +767,8 @@ option(WITH_DOCS
|
||||
"generate YAP docs" OFF)
|
||||
|
||||
IF (WITH_DOCS)
|
||||
get_target_property(YAP_SOURCES libYap SOURCES)
|
||||
|
||||
add_subDIRECTORY(docs)
|
||||
ENDIF (WITH_DOCS)
|
||||
|
||||
|
@ -27,7 +27,6 @@ SET( EXT
|
||||
${DOCS_SOURCE_DIR}/custom/yap.css
|
||||
)
|
||||
|
||||
|
||||
foreach(i ${CMAKE_HTML_EXTRA_})
|
||||
string(APPEND CMAKE_HTML_EXTRA ${i} " ")
|
||||
endforeach(i ${CMAKE_HTML_EXTRA_})
|
||||
@ -88,10 +87,6 @@ endforeach(i ${DOCS_EXCLUDE_})
|
||||
|
||||
set(doxyfile_in ${CMAKE_SOURCE_DIR}/docs/Doxyfile.in)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
add_subdirectory(../packages/raptor/doc ${CMAKE_BINARY_DIR}/packages/raptor/doc)
|
||||
|
||||
SET(DOC_INPUT_FILES_
|
||||
|
@ -13,11 +13,11 @@ predicates in a language other than Prolog. Under Unix systems,
|
||||
most language implementations were linkable to `C`, and the first interface exported the YAP machinery to the C language. YAP also implements most of the SWI-Prolog foreign language interface.
|
||||
This gives portability with a number of SWI-Prolog packages and avoids garnage collection by using @ref slotInterface. Last, a new C++ based interface is
|
||||
being designed to work with the swig (www.swig.orgv) interface compiler.
|
||||
|
||||
@}
|
||||
|
||||
@defgroup ChYInterface YAP original C-interface
|
||||
@{
|
||||
@ingroup fli_c_cxx
|
||||
@{
|
||||
|
||||
Before describing in full detail how to interface to C code, we will examine
|
||||
a brief example.
|
||||
@ -50,8 +50,8 @@ system.
|
||||
@}
|
||||
|
||||
@defgroup CallYAP Using the compiler:
|
||||
@{
|
||||
@ingroup ChYInterface
|
||||
@{
|
||||
|
||||
Under Linux you should use:
|
||||
|
||||
|
@ -1,5 +1,12 @@
|
||||
/**
|
||||
*
|
||||
* @file YapInit.h
|
||||
*
|
||||
* * Utilities for Booting YAP
|
||||
*/
|
||||
|
||||
#ifndef YAPINIT_H
|
||||
#define YAPINIT_H 1
|
||||
#define YAPINIT_H
|
||||
|
||||
#define YAP_BOOT_FROM_SAVED_CODE 1
|
||||
#define YAP_BOOT_FROM_SAVED_STACKS 2
|
||||
|
@ -23,28 +23,30 @@
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
@defgroup args Term Argument Manipulation.
|
||||
|
||||
@ingroup @library
|
||||
|
||||
@{
|
||||
|
||||
Extends arg/3 by including backtracking through arguments and access
|
||||
to sub-arguments,
|
||||
|
||||
- arg0/3
|
||||
- args/3
|
||||
- args0/3
|
||||
- genarg/3
|
||||
- genarg0/3
|
||||
- path_arg/3
|
||||
|
||||
|
||||
It is based on the Quintus Prolog arg library. Except for project, all
|
||||
predicates use the arg/3 argument pattern.
|
||||
This file has been included in the YAP library by Vitor Santos Costa, 2008. No error checking is actuallly performed within the package: this left to the C-code thaat implements arg``/3 and
|
||||
genarg/3.
|
||||
*
|
||||
* @defgroup args Term Argument Manipulation.
|
||||
*
|
||||
* @ingroup @library
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*This library extends arg/3 by supporting backtracking through
|
||||
*arguments and access to sub-arguments,
|
||||
*
|
||||
* - arg0/3
|
||||
* - args/3
|
||||
* - args0/3
|
||||
* - genarg/3
|
||||
* - genarg0/3
|
||||
* - path_arg/3
|
||||
*
|
||||
*
|
||||
*It is based on the Quintus Prolog public domain library. Except for
|
||||
*project, all predicates use the arg/3 argument pattern. This file has
|
||||
*been included in the YAP library by Vitor Santos Costa, 2008.
|
||||
*
|
||||
* No error checking is actuallly performed within the package: this
|
||||
*left to the C-code that implements arg/3 and genarg/3.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -20,8 +20,6 @@
|
||||
* @author VITOR SANTOS COSTA <vsc@VITORs-MBP.lan>
|
||||
* @date Wed Nov 18 01:23:45 2015
|
||||
*
|
||||
* @brief interaction with the OS, be it Unix, Linux, or Windows.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
@ -33,6 +31,7 @@
|
||||
delete_file/1,
|
||||
delete_file/2,
|
||||
directory_files/2,
|
||||
directory_map/2,
|
||||
environ/2,
|
||||
exec/3,
|
||||
file_exists/2,
|
||||
@ -61,7 +60,11 @@
|
||||
working_directory/2
|
||||
]).
|
||||
|
||||
/** @defgroup operating_system_support, Operating System Functionality
|
||||
|
||||
|
||||
/** @defgroup operating_system_support Operating System Functionality
|
||||
* @brief Portable Interaction with the OS, be it Unix, Linux, OSX, or Windows.
|
||||
*
|
||||
@ingroup library
|
||||
@{
|
||||
|
||||
@ -74,13 +77,6 @@ are available through the `use_module(library(system))` command.
|
||||
*/
|
||||
|
||||
|
||||
/** @pred file_exists(+ _File_)
|
||||
|
||||
|
||||
The atom _File_ corresponds to an existing file.
|
||||
|
||||
|
||||
*/
|
||||
/** @pred file_property(+ _File_,? _Property_)
|
||||
|
||||
|
||||
@ -212,13 +208,6 @@ completes. YAP uses `/bin/sh` in Unix systems and `COMSPEC` in
|
||||
WIN32.
|
||||
|
||||
|
||||
*/
|
||||
/** @pred system(+ _Command_,- _Res_)
|
||||
|
||||
Interface to `system`: execute command _Command_ and unify
|
||||
_Res_ with the result.
|
||||
|
||||
|
||||
*/
|
||||
/** @pred tmp_file(+_Base_, - _File_)
|
||||
|
||||
@ -236,21 +225,6 @@ temporary files.
|
||||
Interface with _tmpnam_: obtain a new, unique file name _File_.
|
||||
|
||||
|
||||
*/
|
||||
/** @pred working_directory(- _Old_,+ _New_)
|
||||
|
||||
/** @pred working_directory(- _CurDir_,? _NextDir_)
|
||||
|
||||
|
||||
Fetch the current directory at _CurDir_. If _NextDir_ is bound
|
||||
to an atom, make its value the current working directory.
|
||||
|
||||
Unifies _Old_ with an absolute path to the current working directory
|
||||
and change working directory to _New_. Use the pattern
|
||||
`working_directory(CWD, CWD)` to get the current directory. See
|
||||
also `absolute_file_name/2` and chdir/1.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
:- use_module(library(lists), [append/3]).
|
||||
@ -451,15 +425,11 @@ if there is one. This predicate is backtrackable in Unix systems, but
|
||||
not currently in Win32 configurations.
|
||||
|
||||
~~~~~
|
||||
?- environ('HOME',X).
|
||||
?- environ('HOME',V).
|
||||
|
||||
X = 'C:\\cygwin\\home\\administrator' ?
|
||||
V = 'C:\\cygwin\\home\\administrator' ?
|
||||
~~~~~
|
||||
*/
|
||||
/** @pred environ(+E, -S)
|
||||
|
||||
Given an environment variable _E_ this predicate unifies the second
|
||||
argument _S_ with its value. _E_ may be bound to an atom, or just be
|
||||
_EnvVar_ may be bound to an atom, or just be
|
||||
unbound. In the latter case environ/2 will enumerate over all
|
||||
environment variables.
|
||||
|
||||
@ -666,6 +636,19 @@ get_shell(Shell, '/c') :-
|
||||
getenv('COMSPEC', Shell).
|
||||
get_shell('/bin/sh','-c').
|
||||
|
||||
/**
|
||||
* @pred system(+ _S_)
|
||||
|
||||
Passes command _S_ to the Bourne shell (on UNIX environments) or the
|
||||
current command interpreter in WIN32 environments.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @pred system
|
||||
|
||||
Passes command _S_ to the Bourne shell (on UNIX environments) or the
|
||||
current command interpreter in WIN32 environments.
|
||||
*/
|
||||
system :-
|
||||
default_shell(Command),
|
||||
do_system(Command, _Status, Error),
|
||||
@ -676,6 +659,13 @@ default_shell(Shell) :- win, !,
|
||||
default_shell('/bin/sh').
|
||||
|
||||
|
||||
/** @pred system(+ _Command_,- _Res_)
|
||||
|
||||
Interface to `system`: execute command _Command_ and unify
|
||||
_Res_ with the result.
|
||||
|
||||
|
||||
n*/
|
||||
system(Command, Status) :-
|
||||
G = system(Command, Status),
|
||||
check_command(Command, G),
|
||||
@ -764,13 +754,6 @@ rename_file(F0, F) :-
|
||||
rename_file(F0, F, Error),
|
||||
handle_system_internal(Error, off, rename_file(F0, F)).
|
||||
|
||||
/**
|
||||
* @pred system(+ _S_)
|
||||
|
||||
Passes command _S_ to the Bourne shell (on UNIX environments) or the
|
||||
current command interpreter in WIN32 environments.
|
||||
*/
|
||||
|
||||
/** @pred directory_files(+ _Dir_,+ _List_)
|
||||
|
||||
|
||||
@ -788,4 +771,44 @@ environments, and `findfirst` in WIN32 through the system_library buil
|
||||
directory_files(X,Y) :-
|
||||
list_directory(X,Y).
|
||||
|
||||
:- meta_predicate directory_map(+,1,-),
|
||||
rb_apply(+,+,2,-).
|
||||
|
||||
/** @pred directory_map(+ _Dir_, 1:_P_)
|
||||
|
||||
|
||||
Given a directory _Dir_, directory_map/2 visits all files in _Dir_,
|
||||
and verifies whether `P(F)` holds, where _F_ is the file's absolute
|
||||
path.
|
||||
|
||||
~~~~~
|
||||
?- directory_map('.', process).
|
||||
~~~~~
|
||||
|
||||
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),
|
||||
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)] ),
|
||||
f_map(File, P),
|
||||
d_map(Fs, D, P).
|
||||
|
||||
f_map(File, P) :-
|
||||
catch( file_property( File, type(directory) ), _, fail ),
|
||||
directory_map( File, P).
|
||||
f_map(File, P) :-
|
||||
call(P,File).
|
||||
|
||||
|
||||
|
||||
/** @} */
|
||||
|
13
os/sysbits.c
13
os/sysbits.c
@ -1150,6 +1150,19 @@ const char *Yap_getcwd(char *cwd, size_t cwdlen) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** @pred working_directory( ?_CurDir_,? _NextDir_)
|
||||
|
||||
|
||||
Fetch the current directory at _CurDir_. If _NextDir_ is bound
|
||||
to an atom, make its value the current working directory.
|
||||
|
||||
Unifies _Old_ with an absolute path to the current working directory
|
||||
and change working directory to _New_. Use the pattern
|
||||
`working_directory(CWD, CWD)` to get the current directory. See
|
||||
also `absolute_file_name/2` and chdir/1.
|
||||
|
||||
|
||||
*/
|
||||
static Int working_directory(USES_REGS1) {
|
||||
char dir[YAP_FILENAME_MAX + 1];
|
||||
Term t1 = Deref(ARG1), t2;
|
||||
|
@ -832,7 +832,6 @@ 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_set_parameter(min_step, 0.0, Solver),
|
||||
lbfgs_run(Solver,BestF),
|
||||
format('~2nOptimization done~nWe found a minimum ~4f.~n',[BestF]),
|
||||
forall(tunable_fact(FactID,GroundTruth), set_tunable(FactID,Slope,X)),
|
||||
|
202
pl/callcount.yap
202
pl/callcount.yap
@ -15,57 +15,61 @@
|
||||
* *
|
||||
*************************************************************************/
|
||||
|
||||
%% @{
|
||||
|
||||
/**
|
||||
@file callcount.yap
|
||||
@short support call counting.
|
||||
|
||||
@defgroup Profiling Profiling Prolog Programs
|
||||
@ingroup extensions
|
||||
|
||||
YAP includes two profilers. The count profiler keeps information on the
|
||||
number of times a predicate was called. This information can be used to
|
||||
detect what are the most commonly called predicates in the program. The
|
||||
count profiler can be compiled by setting YAP's flag profiling
|
||||
to `on`. The time-profiler is a `gprof` profiler, and counts
|
||||
how many ticks are being spent on specific predicates, or on other
|
||||
system functions such as internal data-base accesses or garbage collects.
|
||||
|
||||
The YAP profiling sub-system is currently under
|
||||
development. Functionality for this sub-system will increase with newer
|
||||
implementation.
|
||||
|
||||
|
||||
* @file callcount.yap
|
||||
* @short support call counting.
|
||||
*
|
||||
* @defgroup Profiling Profiling Prolog Programs
|
||||
* @brief the clock and the tick profilers.
|
||||
* @ingroup extensions
|
||||
* @{
|
||||
*
|
||||
* YAP includes two profilers. The count profiler keeps information on the
|
||||
* number of times a predicate was called. This information can be used to
|
||||
* detect what are the most commonly called predicates in the program. The
|
||||
* count profiler can be compiled by setting YAP's flag profiling
|
||||
* to `on`. The time-profiler is a `gprof` profiler, and counts
|
||||
* how many ticks are being spent on specific predicates, or on other
|
||||
* system functions such as internal data-base accesses or garbage collects.
|
||||
*
|
||||
* + Call_Counting
|
||||
* +
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup Call_Counting Counting Calls
|
||||
@ingroup Profiling
|
||||
@{
|
||||
|
||||
Predicates compiled with YAP's flag call_counting set to
|
||||
`on` update counters on the numbers of calls and of
|
||||
retries. Counters are actually decreasing counters, so that they can be
|
||||
used as timers. Three counters are available:
|
||||
|
||||
+ `calls`: number of predicate calls since execution started or since
|
||||
system was reset;
|
||||
+ `retries`: number of retries for predicates called since
|
||||
execution started or since counters were reset;
|
||||
+ `calls_and_retries`: count both on predicate calls and
|
||||
retries.
|
||||
|
||||
These counters can be used to find out how many calls a certain
|
||||
goal takes to execute. They can also be used as timers.
|
||||
|
||||
The code for the call counters piggybacks on the profiling
|
||||
code. Therefore, activating the call counters also activates the profiling
|
||||
counters.
|
||||
|
||||
These are the predicates that access and manipulate the call counters.
|
||||
@}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup Call_Counting Counting Calls
|
||||
* @ingroup Profiling
|
||||
* @{
|
||||
*
|
||||
* Predicates compiled with YAP's flag call_counting set to
|
||||
* `on` update counters on the numbers of calls and of
|
||||
* retries. Counters are actually decreasing counters, so that they can be
|
||||
* used as timers. Three counters are available:
|
||||
*
|
||||
* + `calls`: number of predicate calls since execution started or since
|
||||
* system was reset;
|
||||
* + `retries`: number of retries for predicates called since
|
||||
* execution started or since counters were reset;
|
||||
* + `calls_and_retries`: count both on predicate calls and
|
||||
* retries.
|
||||
*
|
||||
* These counters can be used to find out how many calls a certain
|
||||
* goal takes to execute. They can also be used as timers.
|
||||
*
|
||||
* The code for the call counters piggybacks on the profiling
|
||||
* code. Therefore, activating the call counters also activates the profiling
|
||||
* counters.
|
||||
*
|
||||
* These are the predicates that access and manipulate the call counters.
|
||||
* */
|
||||
|
||||
:- system_module( '$_callcount', [call_count/3,
|
||||
call_count_data/3,
|
||||
call_count_reset/0], []).
|
||||
@ -74,68 +78,68 @@ These are the predicates that access and manipulate the call counters.
|
||||
|
||||
|
||||
/** @pred call_count_data(- _Calls_, - _Retries_, - _CallsAndRetries_)
|
||||
|
||||
|
||||
Give current call count data. The first argument gives the current value
|
||||
for the _Calls_ counter, next the _Retries_ counter, and last
|
||||
the _CallsAndRetries_ counter.
|
||||
|
||||
*/
|
||||
*
|
||||
*
|
||||
* Give current call count data. The first argument gives the current value
|
||||
* for the _Calls_ counter, next the _Retries_ counter, and last
|
||||
* the _CallsAndRetries_ counter.
|
||||
*
|
||||
* */
|
||||
call_count_data(Calls, Retries, Both) :-
|
||||
'$call_count_info'(Calls, Retries, Both).
|
||||
|
||||
/** @pred call_count_reset
|
||||
|
||||
|
||||
Reset call count counters. All timers are also reset.
|
||||
|
||||
*
|
||||
*
|
||||
* Reset call count counters. All timers are also reset.
|
||||
*
|
||||
*/
|
||||
call_count_reset :-
|
||||
'$call_count_reset'.
|
||||
|
||||
/** @pred call_count(? _CallsMax_, ? _RetriesMax_, ? _CallsAndRetriesMax_)
|
||||
|
||||
|
||||
Set call counters as timers. YAP will generate an exception
|
||||
if one of the instantiated call counters decreases to 0:
|
||||
|
||||
+ _CallsMax_
|
||||
|
||||
throw the exception `call_counter` when the
|
||||
counter `calls` reaches 0;
|
||||
|
||||
+ _RetriesMax_
|
||||
|
||||
throw the exception `retry_counter` when the
|
||||
counter `retries` reaches 0;
|
||||
|
||||
+ _CallsAndRetriesMax_
|
||||
|
||||
throw the exception
|
||||
`call_and_retry_counter` when the counter `calls_and_retries`
|
||||
reaches 0.
|
||||
|
||||
YAP will ignore counters that are called with unbound arguments.
|
||||
|
||||
Next, we show a simple example of how to use call counters:
|
||||
|
||||
~~~~~{.prolog}
|
||||
?- yap_flag(call_counting,on), [-user]. l :- l. end_of_file. yap_flag(call_counting,off).
|
||||
|
||||
yes
|
||||
|
||||
yes
|
||||
?- catch((call_count(10000,_,_),l),call_counter,format("limit_exceeded.~n",[])).
|
||||
|
||||
limit_exceeded.
|
||||
|
||||
yes
|
||||
~~~~~
|
||||
Notice that we first compile the looping predicate `l/0` with
|
||||
call_counting `on`. Next, we catch/3 to handle an
|
||||
exception when `l/0` performs more than 10000 reductions.
|
||||
|
||||
|
||||
*
|
||||
*
|
||||
* Set call counters as timers. YAP will generate an exception
|
||||
* if one of the instantiated call counters decreases to 0:
|
||||
*
|
||||
* + _CallsMax_
|
||||
*
|
||||
* throw the exception `call_counter` when the
|
||||
* counter `calls` reaches 0;
|
||||
*
|
||||
* + _RetriesMax_
|
||||
*
|
||||
* throw the exception `retry_counter` when the
|
||||
* counter `retries` reaches 0;
|
||||
*
|
||||
* + _CallsAndRetriesMax_
|
||||
*
|
||||
* throw the exception
|
||||
* `call_and_retry_counter` when the counter `calls_and_retries`
|
||||
* reaches 0.
|
||||
*
|
||||
* YAP will ignore counters that are called with unbound arguments.
|
||||
*
|
||||
* Next, we show a simple example of how to use call counters:
|
||||
*
|
||||
* ~~~~~{.prolog}
|
||||
* ?- yap_flag(call_counting,on), [-user]. l :- l. end_of_file. yap_flag(call_counting,off).
|
||||
*
|
||||
* yes
|
||||
*
|
||||
* yes
|
||||
* ?- catch((call_count(10000,_,_),l),call_counter,format("limit_exceeded.~n",[])).
|
||||
*
|
||||
* limit_exceeded.
|
||||
*
|
||||
* yes
|
||||
* ~~~~~
|
||||
* Notice that we first compile the looping predicate `l/0` with
|
||||
* call_counting `on`. Next, we catch/3 to handle an
|
||||
* exception when `l/0` performs more than 10000 reductions.
|
||||
*
|
||||
*
|
||||
*/
|
||||
call_count(Calls, Retries, Both) :-
|
||||
'$check_if_call_count_on'(Calls, CallsOn),
|
||||
@ -150,7 +154,3 @@ call_count(Calls, Retries, Both) :-
|
||||
|
||||
%% @}
|
||||
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
|
||||
|
283
pl/control.yap
283
pl/control.yap
@ -88,80 +88,80 @@
|
||||
*/
|
||||
|
||||
/** @pred forall(: _Cond_,: _Action_)
|
||||
|
||||
|
||||
For all alternative bindings of _Cond_ _Action_ can be
|
||||
proven. The example verifies that all arithmetic statements in the list
|
||||
_L_ are correct. It does not say which is wrong if one proves wrong.
|
||||
|
||||
~~~~~{.prolog}
|
||||
?- forall(member(Result = Formula, [2 = 1 + 1, 4 = 2 * 2]),
|
||||
Result =:= Formula).
|
||||
~~~~~
|
||||
|
||||
|
||||
*
|
||||
*
|
||||
* For all alternative bindings of _Cond_ _Action_ can be
|
||||
* proven. The example verifies that all arithmetic statements in the list
|
||||
* _L_ are correct. It does not say which is wrong if one proves wrong.
|
||||
*
|
||||
* ~~~~~{.prolog}
|
||||
* ?- forall(member(Result = Formula, [2 = 1 + 1, 4 = 2 * 2]),
|
||||
* Result =:= Formula).
|
||||
* ~~~~~
|
||||
*
|
||||
*
|
||||
*/
|
||||
forall(Cond, Action) :- \+((Cond, \+(Action))).
|
||||
|
||||
/** @pred ignore(: _Goal_)
|
||||
|
||||
|
||||
Calls _Goal_ as once/1, but succeeds, regardless of whether
|
||||
`Goal` succeeded or not. Defined as:
|
||||
|
||||
~~~~~{.prolog}
|
||||
ignore(Goal) :-
|
||||
Goal, !.
|
||||
ignore(_).
|
||||
~~~~~
|
||||
|
||||
|
||||
*
|
||||
*
|
||||
* Calls _Goal_ as once/1, but succeeds, regardless of whether
|
||||
* `Goal` succeeded or not. Defined as:
|
||||
*
|
||||
* ~~~~~{.prolog}
|
||||
* ignore(Goal) :-
|
||||
* Goal, !.
|
||||
* ignore(_).
|
||||
* ~~~~~
|
||||
*
|
||||
*
|
||||
*/
|
||||
ignore(Goal) :- (Goal->true;true).
|
||||
|
||||
/** @pred if(? _G_,? _H_,? _I_)
|
||||
|
||||
Call goal _H_ once per each solution of goal _H_. If goal
|
||||
_H_ has no solutions, call goal _I_.
|
||||
|
||||
The built-in `if/3` is similar to `->/3`, with the difference
|
||||
that it will backtrack over the test. Consider the following
|
||||
small data-base:
|
||||
|
||||
~~~~~{.prolog}
|
||||
a(1). b(a). c(x).
|
||||
a(2). b(b). c(y).
|
||||
~~~~~
|
||||
|
||||
Execution of an `if/3` query will proceed as follows:
|
||||
|
||||
~~~~~{.prolog}
|
||||
?- if(a(X),b(Y),c(Z)).
|
||||
|
||||
X = 1,
|
||||
Y = a ? ;
|
||||
|
||||
X = 1,
|
||||
Y = b ? ;
|
||||
|
||||
X = 2,
|
||||
Y = a ? ;
|
||||
|
||||
X = 2,
|
||||
Y = b ? ;
|
||||
|
||||
no
|
||||
~~~~~
|
||||
|
||||
The system will backtrack over the two solutions for `a/1` and the
|
||||
two solutions for `b/1`, generating four solutions.
|
||||
|
||||
Cuts are allowed inside the first goal _G_, but they will only prune
|
||||
over _G_.
|
||||
|
||||
If you want _G_ to be deterministic you should use if-then-else, as
|
||||
it is both more efficient and more portable.
|
||||
|
||||
*
|
||||
* Call goal _H_ once per each solution of goal _H_. If goal
|
||||
* _H_ has no solutions, call goal _I_.
|
||||
*
|
||||
* The built-in `if/3` is similar to `->/3`, with the difference
|
||||
* that it will backtrack over the test. Consider the following
|
||||
* small data-base:
|
||||
*
|
||||
* ~~~~~{.prolog}
|
||||
* a(1). b(a). c(x).
|
||||
* a(2). b(b). c(y).
|
||||
* ~~~~~
|
||||
*
|
||||
* Execution of an `if/3` query will proceed as follows:
|
||||
*
|
||||
* ~~~~~{.prolog}
|
||||
* ?- if(a(X),b(Y),c(Z)).
|
||||
*
|
||||
* X = 1,
|
||||
* Y = a ? ;
|
||||
*
|
||||
* X = 1,
|
||||
* Y = b ? ;
|
||||
*
|
||||
* X = 2,
|
||||
* Y = a ? ;
|
||||
*
|
||||
* X = 2,
|
||||
* Y = b ? ;
|
||||
*
|
||||
* no
|
||||
* ~~~~~
|
||||
*
|
||||
* The system will backtrack over the two solutions for `a/1` and the
|
||||
* two solutions for `b/1`, generating four solutions.
|
||||
*
|
||||
* Cuts are allowed inside the first goal _G_, but they will only prune
|
||||
* over _G_.
|
||||
*
|
||||
* If you want _G_ to be deterministic you should use if-then-else, as
|
||||
* it is both more efficient and more portable.
|
||||
*
|
||||
*/
|
||||
if(X,Y,Z) :-
|
||||
(
|
||||
@ -174,74 +174,13 @@ if(X,Y,Z) :-
|
||||
'$call'(Z,CP,if(X,Y,Z),M)
|
||||
).
|
||||
|
||||
/** @pred call(
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Closure,...,? Ai,...) is iso
|
||||
|
||||
|
||||
Meta-call with extractpattern arguments, where _Closure_ is a closure
|
||||
that is converted into a goal by appending the _Ai_ additional
|
||||
arguments. YAP supports up to 10 extra arguments.
|
||||
|
||||
/** @pred call( Closure,...,? Ai,...) is iso
|
||||
*
|
||||
*
|
||||
* Meta-call with extra pattern arguments, where _Closure_ is a closure
|
||||
* that is converted into a goal by appending the _Ai_ additional
|
||||
* arguments. YAP supports up to 10 extra arguments.
|
||||
*
|
||||
*/
|
||||
call(X,A) :- '$execute'(X,A).
|
||||
|
||||
@ -266,10 +205,10 @@ call(X,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) :- '$execute'(X,A1,A2,A3,A4,A5,A6,A7,A8,A
|
||||
call(X,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11) :- '$execute'(X,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11).
|
||||
|
||||
/** @pred call_cleanup(: _Goal_, : _CleanUpGoal_)
|
||||
|
||||
This is similar to call_cleanup/1 but with an additional
|
||||
_CleanUpGoal_ which gets called after _Goal_ is finished.
|
||||
|
||||
*
|
||||
* This is similar to call_cleanup/1 but with an additional
|
||||
* _CleanUpGoal_ which gets called after _Goal_ is finished.
|
||||
*
|
||||
*/
|
||||
call_cleanup(Goal, Cleanup) :-
|
||||
'$gated_call'( false , Goal,_Catcher, Cleanup) .
|
||||
@ -468,31 +407,19 @@ query_to_answer(G, V, Status, Bindings) :-
|
||||
|
||||
%% @}
|
||||
|
||||
%% @{
|
||||
|
||||
%% @addtogroup Global_Variables
|
||||
%% @{
|
||||
|
||||
/** @pred nb_getval(+ _Name_,- _Value_)
|
||||
|
||||
|
||||
The nb_getval/2 predicate is a synonym for b_getval/2,
|
||||
introduced for compatibility and symmetry. As most scenarios will use
|
||||
a particular global variable either using non-backtrackable or
|
||||
backtrackable assignment, using nb_getval/2 can be used to
|
||||
document that the variable is used non-backtrackable.
|
||||
|
||||
|
||||
*/
|
||||
/** @pred nb_getval(+ _Name_,- _Value_)
|
||||
|
||||
|
||||
The nb_getval/2 predicate is a synonym for b_getval/2, introduced for
|
||||
compatibility and symmetry. As most scenarios will use a particular
|
||||
global variable either using non-backtrackable or backtrackable
|
||||
assignment, using nb_getval/2 can be used to document that the
|
||||
variable is used non-backtrackable.
|
||||
|
||||
|
||||
*
|
||||
*
|
||||
* The nb_getval/2 predicate is a synonym for b_getval/2, introduced for
|
||||
* compatibility and symmetry. As most scenarios will use a particular
|
||||
* global variable either using non-backtrackable or backtrackable
|
||||
* assignment, using nb_getval/2 can be used to document that the
|
||||
* variable is used non-backtrackable.
|
||||
*
|
||||
*/
|
||||
nb_getval(GlobalVariable, Val) :-
|
||||
'__NB_getval__'(GlobalVariable, Val, Error),
|
||||
@ -508,30 +435,18 @@ nb_getval(GlobalVariable, Val) :-
|
||||
|
||||
|
||||
/** @pred b_getval(+ _Name_, - _Value_)
|
||||
|
||||
|
||||
Get the value associated with the global variable _Name_ and unify
|
||||
it with _Value_. Note that this unification may further
|
||||
instantiate the value of the global variable. If this is undesirable
|
||||
the normal precautions (double negation or copy_term/2) must be
|
||||
taken. The b_getval/2 predicate generates errors if _Name_ is not
|
||||
an atom or the requested variable does not exist.
|
||||
|
||||
Notice that for compatibility with other systems _Name_ <em>must</em> be already associated with a term: otherwise the system will generate an error.
|
||||
|
||||
|
||||
*/
|
||||
/** @pred b_getval(+ _Name_,- _Value_)
|
||||
|
||||
|
||||
Get the value associated with the global variable _Name_ and unify
|
||||
it with _Value_. Note that this unification may further instantiate
|
||||
the value of the global variable. If this is undesirable the normal
|
||||
precautions (double negation or copy_term/2) must be taken. The
|
||||
b_getval/2 predicate generates errors if _Name_ is not an atom or
|
||||
the requested variable does not exist.
|
||||
|
||||
|
||||
*
|
||||
*
|
||||
* Get the value associated with the global variable _Name_ and unify
|
||||
* it with _Value_. Note that this unification may further
|
||||
* instantiate the value of the global variable. If this is undesirable
|
||||
* the normal precautions (double negation or copy_term/2) must be
|
||||
* taken. The b_getval/2 predicate generates errors if _Name_ is not
|
||||
* an atom or the requested variable does not exist.
|
||||
*
|
||||
* Notice that for compatibility with other systems _Name_ <em>must</em> be already associated with a term: otherwise the system will generate an error.
|
||||
*
|
||||
*
|
||||
*/
|
||||
b_getval(GlobalVariable, Val) :-
|
||||
'__NB_getval__'(GlobalVariable, Val, Error),
|
||||
@ -548,9 +463,9 @@ b_getval(GlobalVariable, Val) :-
|
||||
|
||||
%% @}
|
||||
|
||||
%% @{
|
||||
|
||||
%% @addtogroup YAPControl
|
||||
%% @{
|
||||
|
||||
/* This is the break predicate,
|
||||
it saves the importante data about current streams and
|
||||
|
153
pl/profile.yap
153
pl/profile.yap
@ -23,83 +23,80 @@
|
||||
showprofres/1], []).
|
||||
|
||||
/**
|
||||
`* @defgroup Exc_Profiling The Exception Based Tick Profiler.
|
||||
* @ingroup Profiling
|
||||
* @{
|
||||
|
||||
The count profiler works by incrementing counters at procedure entry or
|
||||
backtracking. It provides exact information:
|
||||
|
||||
+ Profiling works for both static and dynamic predicates.
|
||||
+ Currently only information on entries and retries to a predicate
|
||||
are maintained. This may change in the future.
|
||||
+ As an example, the following user-level program gives a list of
|
||||
the most often called procedures in a program. The procedure
|
||||
list_profile/0 shows all procedures, irrespective of module, and
|
||||
the procedure list_profile/1 shows the procedures being used in
|
||||
a specific module.
|
||||
|
||||
~~~~~
|
||||
list_profile :-
|
||||
% get number of calls for each profiled procedure
|
||||
setof(D-[M:P|D1],(current_module(M),profile_data(M:P,calls,D),profile_data(M:P,retries,D1)),LP),
|
||||
% output so that the most often called
|
||||
% predicates will come last:
|
||||
write_profile_data(LP).
|
||||
|
||||
list_profile(Module) :-
|
||||
% get number of calls for each profiled procedure
|
||||
setof(D-[Module:P|D1],(profile_data(Module:P,calls,D),profile_data(Module:P,retries,D1)),LP),
|
||||
% output so that the most often called
|
||||
% predicates will come last:
|
||||
write_profile_data(LP).
|
||||
|
||||
write_profile_data([]).
|
||||
write_profile_data([D-[M:P|R]|SLP]) :-
|
||||
% swap the two calls if you want the most often
|
||||
% called predicates first.
|
||||
format('~a:~w: ~32+~t~d~12+~t~d~12+~n', [M,P,D,R]),
|
||||
write_profile_data(SLP).
|
||||
~~~~~
|
||||
|
||||
|
||||
These are the current predicates to access and clear profiling data:
|
||||
|
||||
|
||||
|
||||
*/
|
||||
*
|
||||
* The count profiler works by incrementing counters at procedure entry or
|
||||
* backtracking. It provides exact information:
|
||||
*
|
||||
* + Profiling works for both static and dynamic predicates.
|
||||
* + Currently only information on entries and retries to a predicate
|
||||
* are maintained. This may change in the future.
|
||||
* + As an example, the following user-level program gives a list of
|
||||
* the most often called procedures in a program. The procedure
|
||||
* list_profile/0 shows all procedures, irrespective of module, and
|
||||
* the procedure list_profile/1 shows the procedures being used in
|
||||
* a specific module.
|
||||
*
|
||||
* ~~~~~
|
||||
* list_profile :-
|
||||
* % get number of calls for each profiled procedure
|
||||
* setof(D-[M:P|D1],(current_module(M),profile_data(M:P,calls,D),profile_data(M:P,retries,D1)),LP),
|
||||
* % output so that the most often called
|
||||
* % predicates will come last:
|
||||
* write_profile_data(LP).
|
||||
*
|
||||
* list_profile(Module) :-
|
||||
* % get number of calls for each profiled procedure
|
||||
* setof(D-[Module:P|D1],(profile_data(Module:P,calls,D),profile_data(Module:P,retries,D1)),LP),
|
||||
* % output so that the most often called
|
||||
* % predicates will come last:
|
||||
* write_profile_data(LP).
|
||||
*
|
||||
* write_profile_data([]).
|
||||
* write_profile_data([D-[M:P|R]|SLP]) :-
|
||||
* % swap the two calls if you want the most often
|
||||
* % called predicates first.
|
||||
* format('~a:~w: ~32+~t~d~12+~t~d~12+~n', [M,P,D,R]),
|
||||
* write_profile_data(SLP).
|
||||
* ~~~~~
|
||||
*
|
||||
*
|
||||
* These are the current predicates to access and clear profiling data:
|
||||
*
|
||||
*
|
||||
*
|
||||
**/
|
||||
|
||||
|
||||
:- use_system_module( '$_errors', ['$do_error'/2]).
|
||||
|
||||
|
||||
%% user:prolog_predicate_name()/
|
||||
%
|
||||
% hook predicate, taken from SWI-Prolog, for converting possibly explicitly-
|
||||
% qualified callable terms into an atom that can be used as a label for
|
||||
% describing a predicate; used e.g. on the tick profiler defined below
|
||||
:- multifile(user:prolog_predicate_name/2).
|
||||
|
||||
/** @pred profile_data( ?Na/Ar, ?Parameter, -Data_)
|
||||
|
||||
|
||||
Give current profile data on _Parameter_ for a predicate described
|
||||
by the predicate indicator _Na/Ar_. If any of _Na/Ar_ or
|
||||
_Parameter_ are unbound, backtrack through all profiled predicates
|
||||
or stored parameters. Current parameters are:
|
||||
|
||||
+ calls
|
||||
Number of times a procedure was called.
|
||||
|
||||
+ retries
|
||||
Number of times a call to the procedure was backtracked to and retried.
|
||||
|
||||
|
||||
+ profile_reset
|
||||
|
||||
|
||||
Reset all profiling information.
|
||||
|
||||
|
||||
|
||||
|
||||
*
|
||||
*
|
||||
* Give current profile data on _Parameter_ for a predicate described
|
||||
* by the predicate indicator _Na/Ar_. If any of _Na/Ar_ or
|
||||
* _Parameter_ are unbound, backtrack through all profiled predicates
|
||||
* or stored parameters. Current parameters are:
|
||||
*
|
||||
* + calls
|
||||
* Number of times a procedure was called.
|
||||
*
|
||||
* + retries
|
||||
* Number of times a call to the procedure was backtracked to and retried.
|
||||
*
|
||||
*
|
||||
* + profile_reset
|
||||
* Reset all profiling information.
|
||||
*
|
||||
*/
|
||||
:- meta_predicate profile_data(:,+,-).
|
||||
|
||||
@ -144,24 +141,24 @@ profile_reset :-
|
||||
profile_reset.
|
||||
|
||||
/** @pred showprofres
|
||||
|
||||
|
||||
Show profiling info.
|
||||
|
||||
|
||||
*
|
||||
*
|
||||
* Show profiling counts for all predicates.
|
||||
*
|
||||
*
|
||||
*/
|
||||
showprofres :-
|
||||
showprofres(-1).
|
||||
|
||||
/** @pred showprofres( _N_)
|
||||
|
||||
Show profiling info for the top-most _N_ predicates.
|
||||
|
||||
|
||||
|
||||
The showprofres/0 and `showprofres/1` predicates call a user-defined multifile hook predicate, `user:prolog_predicate_name/2`, that can be used for converting a possibly explicitly-qualified callable term into an atom that will used when printing the profiling information.
|
||||
|
||||
|
||||
*
|
||||
* Show profiling info for the top-most _N_ predicates.
|
||||
*
|
||||
*
|
||||
*
|
||||
* The showprofres/0 and `showprofres/1` predicates call a user-defined multifile hook predicate, `user:prolog_predicate_name/2`, that can be used for converting a possibly explicitly-qualified callable term into an atom that will used when printing the profiling information.
|
||||
*
|
||||
*
|
||||
*/
|
||||
showprofres(A) :-
|
||||
'$offline_showprofres',
|
||||
|
@ -36,8 +36,8 @@
|
||||
/**
|
||||
|
||||
@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
|
||||
|
32
pl/ypp.yap
32
pl/ypp.yap
@ -3,8 +3,6 @@
|
||||
* @author Nuno Fonseca (nunofonseca@acm.org), Tiago Soares
|
||||
* @date 2005-05-14
|
||||
*
|
||||
* @brief Yap PreProcessing
|
||||
*
|
||||
*
|
||||
*/
|
||||
%====================================================================================
|
||||
@ -32,16 +30,18 @@
|
||||
).
|
||||
|
||||
/**
|
||||
* @defgroup Ypp Yap PreProcessing
|
||||
* @defgroup Ypp YAP PreProcessing
|
||||
* @brief YAP Interface to the C Preprocessor
|
||||
*
|
||||
* @{
|
||||
* @ingroup library
|
||||
*
|
||||
* This program can be used as a preprocessor in the
|
||||
* This program allows preprocessing in the
|
||||
* style of the `C` language. Currently, it must be used through
|
||||
* ypp_consult and or ypp_reconsult.
|
||||
* ypp_consult/1 and or ypp_reconsult/1. See the myddas library for examples of use.
|
||||
*
|
||||
* Notice that ypp uses `#` commands and it is different from the Prolog if/1
|
||||
* directive.
|
||||
* directive. The `ypp` extension should be used for these files.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -57,14 +57,26 @@ ypp_state(State):-
|
||||
get_state(State),
|
||||
!.
|
||||
|
||||
/** @pred ypp_define(_Name_,_Value_)
|
||||
*
|
||||
* Define a new preprocessor symbol _Name_, and bind it to _Value_ (same as `#define`)
|
||||
*/
|
||||
ypp_define(Name,Value):-
|
||||
ground(Name),ground(Value),
|
||||
store_define(Name,Value).
|
||||
|
||||
/** @pred ypp_undefine(_Name_)
|
||||
*
|
||||
* Discard a preprocessor symbol _Name_ (same as `#undef`)
|
||||
*/
|
||||
ypp_undefine(Name):-
|
||||
ground(Name),
|
||||
del_define(Name).
|
||||
|
||||
/** @pred ypp_extcmd(_Cmd_)
|
||||
*
|
||||
* Add a preprocessor extension _Cmd_
|
||||
*/
|
||||
ypp_extcmd(Cmd):-
|
||||
ground(Cmd),!,
|
||||
eraseall('____ypp_extcmd'),
|
||||
@ -73,10 +85,18 @@ ypp_extcmd(Cmd):-
|
||||
\+ ground(Cmd),
|
||||
recorded('____ypp_extcmd',Cmd,_).
|
||||
|
||||
/** @pred ypp_consult(_File_)
|
||||
*
|
||||
* Preprocess and consult a file.
|
||||
*/
|
||||
ypp_consult(File):-
|
||||
(get_state(on)->ypp_file(File,NFile);NFile=File),
|
||||
consult(NFile).
|
||||
|
||||
/** @pred ypp_reconsult(_File_)
|
||||
*
|
||||
* Preprocess and reconsult a file.
|
||||
*/
|
||||
ypp_reconsult(File):-
|
||||
(get_state(on)->ypp_file(File,NFile);NFile=File),
|
||||
reconsult(NFile).
|
||||
|
@ -108,7 +108,7 @@ sicstus :- catch(current_prolog_flag(system_type, _), _, fail).
|
||||
|
||||
:- if(swi).
|
||||
throw_error(Error_term,Impldef) :-
|
||||
throw(error(Error_term,context(Impldef,_))).
|
||||
throw(error(Error_term,Impldef)).
|
||||
|
||||
:- set_prolog_flag(generate_debug_info, false).
|
||||
:- use_module(library(option)).
|
||||
@ -126,9 +126,9 @@ set_test_flag(Name, Value) :-
|
||||
throw_error(Error_term,Impldef) :-
|
||||
throw(error(Error_term,i(Impldef))). % SICStus 3 work around
|
||||
|
||||
:- use_module(swi). % SWI-Compatibility
|
||||
%:- use_module(swi). % SWI-Compatibility
|
||||
:- use_module(library(terms)).
|
||||
:- op(700, xfx, =@=).
|
||||
%:- op(700, xfx, =@=).
|
||||
|
||||
'$set_source_module'( In, Out) :-
|
||||
current_source_module(In, Out).
|
||||
@ -159,7 +159,7 @@ set_test_flag( Name, Val ) :-
|
||||
retractall(test_flag(Name,_)),
|
||||
asserta(test_flag(Name, Val)).
|
||||
|
||||
:- op(1150, fx, thread_local).
|
||||
%:- op(1150, fx, thread_local).
|
||||
|
||||
user:term_expansion((:- thread_local(PI)), (:- dynamic(PI))) :-
|
||||
prolog_load_context(module, plunit).
|
||||
@ -255,7 +255,6 @@ loading_tests :-
|
||||
% unit is ended by :- end_tests(UnitName).
|
||||
|
||||
begin_tests(Unit) :-
|
||||
trace,
|
||||
begin_tests(Unit, []).
|
||||
|
||||
begin_tests(Unit, Options) :-
|
||||
@ -268,29 +267,30 @@ begin_tests(Unit, Options) :-
|
||||
:- if(swi).
|
||||
begin_tests(Unit, Name, File:Line, Options) :-
|
||||
loading_tests, !,
|
||||
'$set_source_module'(Context, Context),
|
||||
prolog_flag(typein_module,Context, Context),
|
||||
( current_unit(Unit, Name, Context, Options)
|
||||
-> true
|
||||
; retractall(current_unit(Unit, Name, _, _)),
|
||||
assert(current_unit(Unit, Name, Context, Options))
|
||||
),
|
||||
'$set_source_module'(Old, Name),
|
||||
'$declare_module'(Name, test, Context, File, Line, false),
|
||||
prolog_flag(typein_module,Old, Name),
|
||||
declare_module(Name, test, Context, File, Line, false),
|
||||
discontiguous(Name:'unit test'/4),
|
||||
% '$set_predicate_attribute'(Name:'unit test'/4, trace, 0),
|
||||
discontiguous(Name:'unit body'/2),
|
||||
multifile(Name:'unit test'/4),
|
||||
multifile(Name:'unit body'/2),
|
||||
asserta(loading_unit(Unit, Name, File, Old)).
|
||||
begin_tests(Unit, Name, File:_Line, _Options) :-
|
||||
'$set_source_module'(Old, Old),
|
||||
prolog_flag(typein_module,Old, Old),
|
||||
asserta(loading_unit(Unit, Name, File, Old)).
|
||||
|
||||
'$declare_module'( Name, Class, Context, File, Line, _AllowFile ) :-
|
||||
declare_module( Name, Class, Context, File, Line, _AllowFile ) :-
|
||||
Name \= Context,
|
||||
!,
|
||||
set_module_property( Name, base(Context) ),
|
||||
set_module_property( Name, class(Class) ),
|
||||
set_module_property( Name, exports([], File, Line) ).
|
||||
'$declare_module'( Name, _Class, Name, _File, _Line, _AllowFile ) .
|
||||
declare_module( Name, _Class, Name, _File, _Line, _AllowFile ) .
|
||||
|
||||
:- else.
|
||||
|
||||
@ -327,7 +327,7 @@ end_tests(Unit) :-
|
||||
loading_unit(StartUnit, _, _, _), !,
|
||||
( Unit == StartUnit
|
||||
-> once(retract(loading_unit(StartUnit, _, _, Old))),
|
||||
'$set_source_module'(_, Old)
|
||||
prolog_flag(typein_module,_, Old)
|
||||
; throw_error(context_error(plunit_close(Unit, StartUnit)), _)
|
||||
).
|
||||
end_tests(Unit) :-
|
||||
@ -463,7 +463,7 @@ user:term_expansion(Term, Expanded) :-
|
||||
*******************************/
|
||||
|
||||
:- if(swi).
|
||||
%:- use_module(library(error)).
|
||||
:- use_module(library(error)).
|
||||
:- else.
|
||||
must_be(list, X) :- !,
|
||||
( is_list(X)
|
||||
@ -689,7 +689,7 @@ make_run_tests(Files) :-
|
||||
|
||||
:- if(swi).
|
||||
|
||||
unification_capability(sto_error_incomplete).
|
||||
%unification_capability(sto_error_incomplete).
|
||||
% can detect some (almost all) STO runs
|
||||
unification_capability(rational_trees).
|
||||
unification_capability(finite_trees).
|
||||
@ -701,6 +701,7 @@ set_unification_capability(Cap) :-
|
||||
current_unification_capability(Cap) :-
|
||||
current_prolog_flag(occurs_check, Flag),
|
||||
cap_to_flag(Cap, Flag), !.
|
||||
current_unification_capability(false).
|
||||
|
||||
cap_to_flag(sto_error_incomplete, error).
|
||||
cap_to_flag(rational_trees, false).
|
||||
@ -1033,7 +1034,7 @@ cmp(Var =@= Value, Var, variant, Value). % variant/2 is the same =@=
|
||||
% True if Goal succeeded. Det is unified to =true= if Goal left
|
||||
% no choicepoints and =false= otherwise.
|
||||
|
||||
:- if((swi|sicstus)).
|
||||
:- if((swi)).
|
||||
call_det(Goal, Det) :-
|
||||
call_cleanup(Goal,Det0=true),
|
||||
( var(Det0) -> Det = false ; Det = true ).
|
||||
|
Reference in New Issue
Block a user