fix undefined procedures to allow hooks as before.
This commit is contained in:
parent
b108380cfc
commit
f6bcb22b7c
@ -8159,6 +8159,7 @@ Yap_absmi(int inp)
|
|||||||
PELOCK(19,pe);
|
PELOCK(19,pe);
|
||||||
#endif
|
#endif
|
||||||
if ((pe->PredFlags & (DynamicPredFlag|LogUpdatePredFlag|MultiFileFlag)) ||
|
if ((pe->PredFlags & (DynamicPredFlag|LogUpdatePredFlag|MultiFileFlag)) ||
|
||||||
|
CurrentModule == PROLOG_MODULE ||
|
||||||
(UndefCode->OpcodeOfPred == UNDEF_OPCODE)) {
|
(UndefCode->OpcodeOfPred == UNDEF_OPCODE)) {
|
||||||
#if defined(YAPOR) || defined(THREADS)
|
#if defined(YAPOR) || defined(THREADS)
|
||||||
PP = NULL;
|
PP = NULL;
|
||||||
@ -8207,6 +8208,7 @@ Yap_absmi(int inp)
|
|||||||
ENDD(d0);
|
ENDD(d0);
|
||||||
HR[0] = Yap_Module_Name(pe);
|
HR[0] = Yap_Module_Name(pe);
|
||||||
ARG1 = (Term) AbsPair(HR);
|
ARG1 = (Term) AbsPair(HR);
|
||||||
|
ARG2 = MkIntTerm(getUnknownModule(Yap_GetModuleEntry(HR[0])));
|
||||||
HR += 2;
|
HR += 2;
|
||||||
#ifdef LOW_LEVEL_TRACER
|
#ifdef LOW_LEVEL_TRACER
|
||||||
if (Yap_do_low_level_trace)
|
if (Yap_do_low_level_trace)
|
||||||
|
14
C/modules.c
14
C/modules.c
@ -27,11 +27,6 @@ static Int p_current_module( USES_REGS1 );
|
|||||||
static Int p_current_module1( USES_REGS1 );
|
static Int p_current_module1( USES_REGS1 );
|
||||||
static ModEntry *LookupModule(Term a);
|
static ModEntry *LookupModule(Term a);
|
||||||
|
|
||||||
unsigned int
|
|
||||||
getUnknownModule(ModEntry * m) {
|
|
||||||
return m->flags & UNKNOWN_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static ModEntry *
|
inline static ModEntry *
|
||||||
FetchModuleEntry(Atom at)
|
FetchModuleEntry(Atom at)
|
||||||
/* get predicate entry for ap/arity; create it if neccessary. */
|
/* get predicate entry for ap/arity; create it if neccessary. */
|
||||||
@ -90,6 +85,15 @@ GetModuleEntry(Atom at)
|
|||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
getUnknownModule(ModEntry * m) {
|
||||||
|
if (m && m->flags & UNKNOWN_MASK)
|
||||||
|
return m->flags & UNKNOWN_MASK;
|
||||||
|
else {
|
||||||
|
return GetModuleEntry(AtomUser)->flags & UNKNOWN_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#define ByteAdr(X) ((char *) &(X))
|
#define ByteAdr(X) ((char *) &(X))
|
||||||
Term
|
Term
|
||||||
|
@ -121,7 +121,7 @@
|
|||||||
|
|
||||||
|
|
||||||
CreepCode = RepPredProp(PredPropByFunc(Yap_MkFunctor(AtomCreep,1),PROLOG_MODULE));
|
CreepCode = RepPredProp(PredPropByFunc(Yap_MkFunctor(AtomCreep,1),PROLOG_MODULE));
|
||||||
UndefCode = RepPredProp(PredPropByFunc(Yap_MkFunctor(AtomUndefp,1),PROLOG_MODULE));
|
UndefCode = RepPredProp(PredPropByFunc(Yap_MkFunctor(AtomUndefp,2),PROLOG_MODULE));
|
||||||
SpyCode = RepPredProp(PredPropByFunc(Yap_MkFunctor(AtomSpy,1),PROLOG_MODULE));
|
SpyCode = RepPredProp(PredPropByFunc(Yap_MkFunctor(AtomSpy,1),PROLOG_MODULE));
|
||||||
PredFail = RepPredProp(PredPropByAtom(AtomFail,PROLOG_MODULE));
|
PredFail = RepPredProp(PredPropByAtom(AtomFail,PROLOG_MODULE));
|
||||||
PredTrue = RepPredProp(PredPropByAtom(AtomTrue,PROLOG_MODULE));
|
PredTrue = RepPredProp(PredPropByAtom(AtomTrue,PROLOG_MODULE));
|
||||||
|
@ -356,6 +356,7 @@ PL_SOURCES= \
|
|||||||
pl/strict_iso.yap \
|
pl/strict_iso.yap \
|
||||||
pl/tabling.yap pl/threads.yap \
|
pl/tabling.yap pl/threads.yap \
|
||||||
pl/udi.yap \
|
pl/udi.yap \
|
||||||
|
pl/undefined.yap \
|
||||||
pl/utils.yap \
|
pl/utils.yap \
|
||||||
pl/history.pl \
|
pl/history.pl \
|
||||||
pl/swi.yap \
|
pl/swi.yap \
|
||||||
|
@ -129,7 +129,7 @@ UInt pred_hash_table_size PredHashTableSize void
|
|||||||
|
|
||||||
/* Well-Known Predicates */
|
/* Well-Known Predicates */
|
||||||
struct pred_entry *creep_code CreepCode MkPred AtomCreep 1 PROLOG_MODULE
|
struct pred_entry *creep_code CreepCode MkPred AtomCreep 1 PROLOG_MODULE
|
||||||
struct pred_entry *undef_code UndefCode MkPred AtomUndefp 1 PROLOG_MODULE
|
struct pred_entry *undef_code UndefCode MkPred AtomUndefp 2 PROLOG_MODULE
|
||||||
struct pred_entry *spy_code SpyCode MkPred AtomSpy 1 PROLOG_MODULE
|
struct pred_entry *spy_code SpyCode MkPred AtomSpy 1 PROLOG_MODULE
|
||||||
struct pred_entry *pred_fail PredFail MkPred AtomFail 0 PROLOG_MODULE
|
struct pred_entry *pred_fail PredFail MkPred AtomFail 0 PROLOG_MODULE
|
||||||
struct pred_entry *pred_true PredTrue MkPred AtomTrue 0 PROLOG_MODULE
|
struct pred_entry *pred_true PredTrue MkPred AtomTrue 0 PROLOG_MODULE
|
||||||
|
@ -287,6 +287,7 @@ setUnknown(term_t value, atom_t a, Module m)
|
|||||||
else
|
else
|
||||||
return PL_error(NULL, 0, NULL, ERR_DOMAIN, ATOM_unknown, value);
|
return PL_error(NULL, 0, NULL, ERR_DOMAIN, ATOM_unknown, value);
|
||||||
|
|
||||||
|
#ifndef __YAP_PROLOG__
|
||||||
if ( !(flags&UNKNOWN_ERROR) && (m == MODULE_user || m == MODULE_system) )
|
if ( !(flags&UNKNOWN_ERROR) && (m == MODULE_user || m == MODULE_system) )
|
||||||
{ GET_LD
|
{ GET_LD
|
||||||
|
|
||||||
@ -298,11 +299,10 @@ setUnknown(term_t value, atom_t a, Module m)
|
|||||||
ATOM_modify, ATOM_flag, key);
|
ATOM_modify, ATOM_flag, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __YAP_PROLOG__
|
|
||||||
if ( !SYSTEM_MODE )
|
if ( !SYSTEM_MODE )
|
||||||
printMessage(ATOM_warning, PL_CHARS, "unknown_in_module_user");
|
printMessage(ATOM_warning, PL_CHARS, "unknown_in_module_user");
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
m->flags = flags;
|
m->flags = flags;
|
||||||
|
|
||||||
@ -1203,11 +1203,7 @@ initPrologFlags(void)
|
|||||||
setPrologFlag("occurs_check", FT_ATOM, "false");
|
setPrologFlag("occurs_check", FT_ATOM, "false");
|
||||||
setPrologFlag("access_level", FT_ATOM, "user");
|
setPrologFlag("access_level", FT_ATOM, "user");
|
||||||
setPrologFlag("double_quotes", FT_ATOM, "codes");
|
setPrologFlag("double_quotes", FT_ATOM, "codes");
|
||||||
#ifdef __YAP_PROLOG__
|
|
||||||
setPrologFlag("unknown", FT_ATOM, "fail");
|
|
||||||
#else
|
|
||||||
setPrologFlag("unknown", FT_ATOM, "error");
|
setPrologFlag("unknown", FT_ATOM, "error");
|
||||||
#endif
|
|
||||||
setPrologFlag("debug", FT_BOOL, FALSE, 0);
|
setPrologFlag("debug", FT_BOOL, FALSE, 0);
|
||||||
setPrologFlag("verbose", FT_ATOM|FF_KEEP, GD->options.silent ? "silent" : "normal");
|
setPrologFlag("verbose", FT_ATOM|FF_KEEP, GD->options.silent ? "silent" : "normal");
|
||||||
setPrologFlag("verbose_load", FT_ATOM, "normal");
|
setPrologFlag("verbose_load", FT_ATOM, "normal");
|
||||||
|
@ -310,7 +310,9 @@ do_continuation(Continuation, Module1) :-
|
|||||||
|
|
||||||
execute_continuation(Continuation, Module1) :-
|
execute_continuation(Continuation, Module1) :-
|
||||||
'$undefined'(Continuation, Module1), !,
|
'$undefined'(Continuation, Module1), !,
|
||||||
'$undefp'([Module1|Continuation]).
|
'$current_module'( M ),
|
||||||
|
'$swi_current_prolog_flag'( M:unknown, Default ),
|
||||||
|
'$undefp'([Module1|Continuation] , Default ).
|
||||||
execute_continuation(Continuation, Mod) :-
|
execute_continuation(Continuation, Mod) :-
|
||||||
% do not do meta-expansion nor any fancy stuff.
|
% do not do meta-expansion nor any fancy stuff.
|
||||||
'$execute0'(Continuation, Mod).
|
'$execute0'(Continuation, Mod).
|
||||||
|
91
pl/boot.yap
91
pl/boot.yap
@ -1572,98 +1572,7 @@ log_event( String, Args ) :-
|
|||||||
format( atom( M ), String, Args),
|
format( atom( M ), String, Args),
|
||||||
log_event( M ).
|
log_event( M ).
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@}
|
@}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup Undefined_Procedures Handling Undefined Procedures
|
|
||||||
@ingroup YAPControl
|
|
||||||
@{
|
|
||||||
|
|
||||||
A predicate in a module is said to be undefined if there are no clauses
|
|
||||||
defining the predicate, and if the predicate has not been declared to be
|
|
||||||
dynamic. What YAP does when trying to execute undefined predicates can
|
|
||||||
be specified in three different ways:
|
|
||||||
|
|
||||||
|
|
||||||
+ By setting an YAP flag, through the yap_flag/2 or
|
|
||||||
set_prolog_flag/2 built-ins. This solution generalizes the
|
|
||||||
ISO standard.
|
|
||||||
+ By using the unknown/2 built-in (this solution is
|
|
||||||
compatible with previous releases of YAP).
|
|
||||||
+ By defining clauses for the hook predicate
|
|
||||||
`user:unknown_predicate_handler/3`. This solution is compatible
|
|
||||||
with SICStus Prolog.
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
% Called by the abstract machine, if no clauses exist for a predicate
|
|
||||||
'$undefp'([M|G]) :-
|
|
||||||
'$find_goal_definition'(M, G, NM, NG),
|
|
||||||
'$execute0'(NG, NM).
|
|
||||||
|
|
||||||
'$find_goal_definition'(M, G, NM, NG) :-
|
|
||||||
% make sure we do not loop on undefined predicates
|
|
||||||
% for undefined_predicates.
|
|
||||||
'$enter_undefp',
|
|
||||||
(
|
|
||||||
'$get_undefined_pred'(G, M, Goal, NM)
|
|
||||||
->
|
|
||||||
'$exit_undefp',
|
|
||||||
Goal \= fail,
|
|
||||||
'$complete_goal'(M, Goal, NM, G, NG)
|
|
||||||
;
|
|
||||||
'$find_undefp_handler'(G, M),
|
|
||||||
NG = G, NM = M
|
|
||||||
).
|
|
||||||
|
|
||||||
'$complete_goal'(M, G, CurMod, G0, NG) :-
|
|
||||||
(
|
|
||||||
'$is_metapredicate'(G,CurMod)
|
|
||||||
->
|
|
||||||
'$meta_expansion'(G, M, CurMod, M, NG,[])
|
|
||||||
;
|
|
||||||
NG = G
|
|
||||||
).
|
|
||||||
|
|
||||||
'$find_undefp_handler'(G,M,NG,user) :-
|
|
||||||
functor(G, Na, Ar),
|
|
||||||
user:exception(undefined_predicate,M:Na/Ar,Action), !,
|
|
||||||
'$exit_undefp',
|
|
||||||
(
|
|
||||||
Action == fail
|
|
||||||
->
|
|
||||||
NG = fail
|
|
||||||
;
|
|
||||||
Action == retry
|
|
||||||
->
|
|
||||||
NG = G
|
|
||||||
;
|
|
||||||
Action == error
|
|
||||||
->
|
|
||||||
'$unknown_error'(M:G)
|
|
||||||
;
|
|
||||||
'$do_error'(type_error(atom, Action),M:G)
|
|
||||||
).
|
|
||||||
|
|
||||||
'$find_undefp_handler'(G,M) :-
|
|
||||||
'$exit_undefp',
|
|
||||||
'$swi_current_prolog_flag'(M:unknown, Action),
|
|
||||||
(
|
|
||||||
Action == fail
|
|
||||||
->
|
|
||||||
fail
|
|
||||||
;
|
|
||||||
Action == warning
|
|
||||||
->
|
|
||||||
'$unknown_warning'(M:G),
|
|
||||||
fail
|
|
||||||
;
|
|
||||||
'$unknown_error'(M:G)
|
|
||||||
).
|
|
||||||
|
|
||||||
/**
|
|
||||||
@}
|
|
||||||
*/
|
|
||||||
|
@ -182,6 +182,8 @@ version(yap,[6,3]).
|
|||||||
|
|
||||||
:- ['arrays.yap'].
|
:- ['arrays.yap'].
|
||||||
|
|
||||||
|
:- ['undefined.yap'].
|
||||||
|
|
||||||
:- use_module('messages.yap').
|
:- use_module('messages.yap').
|
||||||
:- use_module('hacks.yap').
|
:- use_module('hacks.yap').
|
||||||
:- use_module('attributes.yap').
|
:- use_module('attributes.yap').
|
||||||
@ -334,7 +336,7 @@ If this hook predicate succeeds it must instantiate the _Action_ argument to th
|
|||||||
|
|
||||||
:- dynamic user:exception/3.
|
:- dynamic user:exception/3.
|
||||||
|
|
||||||
:- yap_flag(user:unknown,error).
|
:- yap_flag(unknown,error).
|
||||||
|
|
||||||
:- stream_property(user_input, tty(true)) -> set_prolog_flag(readline, true) ; true.
|
:- stream_property(user_input, tty(true)) -> set_prolog_flag(readline, true) ; true.
|
||||||
|
|
||||||
|
@ -1093,7 +1093,6 @@ its parent goal.
|
|||||||
setup_call_catcher_cleanup(0,0,?,0),
|
setup_call_catcher_cleanup(0,0,?,0),
|
||||||
spy(:),
|
spy(:),
|
||||||
stash_predicate(:),
|
stash_predicate(:),
|
||||||
unknown(+,:),
|
|
||||||
use_module(:),
|
use_module(:),
|
||||||
use_module(:,?),
|
use_module(:,?),
|
||||||
use_module(?,:,?),
|
use_module(?,:,?),
|
||||||
|
84
pl/preds.yap
84
pl/preds.yap
@ -892,11 +892,11 @@ abolish(X) :-
|
|||||||
functor(G,Name,Arity),
|
functor(G,Name,Arity),
|
||||||
print_message(warning,no_match(abolish(Module:Name/Arity))).
|
print_message(warning,no_match(abolish(Module:Name/Arity))).
|
||||||
'$abolishs'(G, M) :-
|
'$abolishs'(G, M) :-
|
||||||
'$is_multifile'(G,M), !,
|
'$is_multifile'(G,M),
|
||||||
functor(G,Name,Arity),
|
functor(G,Name,Arity),
|
||||||
recorded('$mf','$mf_clause'(_,Name,Arity,M,Ref),R),
|
recorded('$mf','$mf_clause'(_,Name,Arity,M,_Ref),R),
|
||||||
erase(R),
|
erase(R),
|
||||||
erase(Ref),
|
% no need erase(Ref),
|
||||||
fail.
|
fail.
|
||||||
'$abolishs'(T, M) :-
|
'$abolishs'(T, M) :-
|
||||||
recorded('$import','$import'(_,M,_,_,T,_,_),R),
|
recorded('$import','$import'(_,M,_,_,T,_,_),R),
|
||||||
@ -1369,81 +1369,3 @@ clause_property(ClauseRef, predicate(PredicateIndicator)) :-
|
|||||||
@}
|
@}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
|
|
||||||
@addtogroup Undefined_Procedures
|
|
||||||
@{
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/** @pred unknown(- _O_,+ _N_)
|
|
||||||
|
|
||||||
|
|
||||||
Specifies an handler to be called is a program tries to call an
|
|
||||||
undefined static procedure _P_.
|
|
||||||
|
|
||||||
The arity of _N_ may be zero or one. If the arity is `0`, the
|
|
||||||
new action must be one of `fail`, `warning`, or
|
|
||||||
`error`. If the arity is `1`, _P_ is an user-defined
|
|
||||||
handler and at run-time, the argument to the handler _P_ will be
|
|
||||||
unified with the undefined goal. Note that _N_ must be defined prior
|
|
||||||
to calling unknown/2, and that the single argument to _N_ must
|
|
||||||
be unbound.
|
|
||||||
|
|
||||||
In YAP, the default action is to `fail` (note that in the ISO
|
|
||||||
Prolog standard the default action is `error`).
|
|
||||||
|
|
||||||
After defining `undefined/1` by:
|
|
||||||
|
|
||||||
~~~~~{.prolog}
|
|
||||||
undefined(A) :- format('Undefined predicate: ~w~n',[A]), fail.
|
|
||||||
~~~~~
|
|
||||||
and executing the goal:
|
|
||||||
|
|
||||||
~~~~~{.prolog}
|
|
||||||
unknown(U,undefined(X)).
|
|
||||||
~~~~~
|
|
||||||
a call to a predicate for which no clauses were defined will result in
|
|
||||||
the output of a message of the form:
|
|
||||||
|
|
||||||
~~~~~{.prolog}
|
|
||||||
Undefined predicate: user:xyz(A1,A2)
|
|
||||||
~~~~~
|
|
||||||
followed by the failure of that call.
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
unknown(V0, V) :-
|
|
||||||
strip_module(V, M, G),
|
|
||||||
recorded('$unknown_handle', M0:G0, R), !,
|
|
||||||
recordz('$unknown_handle', M:G, _),
|
|
||||||
erase( R ),
|
|
||||||
strip_module(V0, M0, G0).
|
|
||||||
unknown(V0, V) :-
|
|
||||||
strip_module(V, M, G),
|
|
||||||
recordz('$unknown_handle', M:G, _),
|
|
||||||
V0 = fail.
|
|
||||||
|
|
||||||
%%% The unknown predicate,
|
|
||||||
% informs about what the user wants to be done when
|
|
||||||
% there are no clauses for a certain predicate */
|
|
||||||
|
|
||||||
'$unknown_error'(Call) :-
|
|
||||||
recorded( '$unknown_handle', M:Goal, _),
|
|
||||||
arg(1, Goal, Call), !,
|
|
||||||
once(M:Goal).
|
|
||||||
'$unknown_error'(Mod:Goal) :-
|
|
||||||
functor(Goal,Name,Arity),
|
|
||||||
'$program_continuation'(PMod,PName,PAr),
|
|
||||||
'$do_error'(existence_error(procedure,Name/Arity),context(Mod:Goal,PMod:PName/PAr)).
|
|
||||||
|
|
||||||
'$unknown_warning'(Mod:Goal) :-
|
|
||||||
functor(Goal,Name,Arity),
|
|
||||||
'$program_continuation'(PMod,PName,PAr),
|
|
||||||
print_message(error,error(existence_error(procedure,Name/Arity), context(Mod:Goal,PMod:PName/PAr))),
|
|
||||||
fail.
|
|
||||||
|
|
||||||
/**
|
|
||||||
@}
|
|
||||||
*/
|
|
||||||
|
130
pl/undefined.yap
Normal file
130
pl/undefined.yap
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/*************************************************************************
|
||||||
|
* *
|
||||||
|
* YAP Prolog *
|
||||||
|
* *
|
||||||
|
* Yap Prolog was developed at NCCUP - Universidade do Porto *
|
||||||
|
* *
|
||||||
|
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
|
||||||
|
* *
|
||||||
|
**************************************************************************
|
||||||
|
* *
|
||||||
|
* File: undefined.yap *
|
||||||
|
* Last rev: 8/2/88 *
|
||||||
|
* mods: *
|
||||||
|
* comments: Predicate Undefined for YAP *
|
||||||
|
* *
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
/** @defgroup Undefined_Procedures Handling Undefined Procedures
|
||||||
|
@ingroup YAPControl
|
||||||
|
@{
|
||||||
|
|
||||||
|
A predicate in a module is said to be undefined if there are no clauses
|
||||||
|
defining the predicate, and if the predicate has not been declared to be
|
||||||
|
dynamic. What YAP does when trying to execute undefined predicates can
|
||||||
|
be specified in three different ways:
|
||||||
|
|
||||||
|
|
||||||
|
+ By setting an YAP flag, through the yap_flag/2 or
|
||||||
|
set_prolog_flag/2 built-ins. This solution generalizes the
|
||||||
|
ISO standard by allowing module-specific behavior.
|
||||||
|
+ By using the unknown/2 built-in (this deprecated solution is
|
||||||
|
compatible with previous releases of YAP).
|
||||||
|
+ By defining clauses for the hook predicate
|
||||||
|
`user:unknown_predicate_handler/3`. This solution is compatible
|
||||||
|
with SICStus Prolog.
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'$undefp'([M0|G0], Default) :-
|
||||||
|
% make sure we do not loop on undefined predicates
|
||||||
|
% for undefined_predicates.
|
||||||
|
'$enter_undefp',
|
||||||
|
(
|
||||||
|
'$get_undefined_pred'(G0, M0, Goal, NM)
|
||||||
|
->
|
||||||
|
'$exit_undefp',
|
||||||
|
Goal \= fail,
|
||||||
|
'$complete_goal'(M0, G0, Goal, NM, NG),
|
||||||
|
'$execute0'(NG, NM)
|
||||||
|
;
|
||||||
|
user:unknown_predicate_handler(G0,M0,NG)
|
||||||
|
->
|
||||||
|
call(M:NG)
|
||||||
|
;
|
||||||
|
'$exit_undefp',
|
||||||
|
'$handle_error'(Default,G0,M0)
|
||||||
|
).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** @pred unknown(- _O_,+ _N_)
|
||||||
|
|
||||||
|
The unknown predicate, informs about what the user wants to be done
|
||||||
|
when there are no clauses for a certain predicate.
|
||||||
|
|
||||||
|
This predicate is strongly deprecated. Use prolog_flag for generic
|
||||||
|
behaviour, and user:unknown_predicate_handler/3 for flexible behaviour
|
||||||
|
on undefined goals.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
unknown(P, NP) :-
|
||||||
|
prolog_flag( unknown, P, NP ).
|
||||||
|
|
||||||
|
/** @pred user:unknown_predicate_handler(+ _Call_, + _M_, - _N_)
|
||||||
|
|
||||||
|
In YAP, the default action on undefined predicates is to output an
|
||||||
|
`error` message. Alternatives are to silently `fail`, or to print a
|
||||||
|
`warning` message and then fail. This follows the ISO Prolog standard
|
||||||
|
where the default action is `error`.
|
||||||
|
|
||||||
|
The user:unknown_predicate_handler/3 hook was originally include in
|
||||||
|
SICStus Prolog. It allows redefining the answer for specifici
|
||||||
|
calls. As an example. after defining `undefined/1` by:
|
||||||
|
|
||||||
|
~~~~~{.prolog}
|
||||||
|
undefined(A) :- format('Undefined predicate: ~w~n',[A]), fail.
|
||||||
|
~~~~~
|
||||||
|
and executing the goal:
|
||||||
|
|
||||||
|
~~~~~{.prolog}
|
||||||
|
:- assert(user:unknown_predicate_handler(U,M,undefined(M:U)) )
|
||||||
|
~~~~~
|
||||||
|
a call to a predicate for which no clauses were defined will result in
|
||||||
|
the output of a message of the form:
|
||||||
|
|
||||||
|
~~~~~{.prolog}
|
||||||
|
Undefined predicate: user:xyz(A1,A2)
|
||||||
|
~~~~~
|
||||||
|
followed by the failure of that call.
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
:- multifile user:unknown_predicate_handler/3.
|
||||||
|
|
||||||
|
'$handle_error'(0x0080,Goal,Mod) :-
|
||||||
|
functor(Goal,Name,Arity),
|
||||||
|
'$program_continuation'(PMod,PName,PAr),
|
||||||
|
'$do_error'(existence_error(procedure,Name/Arity),context(Mod:Goal,PMod:PName/PAr)).
|
||||||
|
'$handle_error'(0x0040,Goal,Mod) :-
|
||||||
|
functor(Goal,Name,Arity),
|
||||||
|
'$program_continuation'(PMod,PName,PAr),
|
||||||
|
print_message(warning,error(existence_error(procedure,Name/Arity), context(Mod:Goal,PMod:PName/PAr))),
|
||||||
|
fail.
|
||||||
|
'$handle_error'(0x0020,_Goal,_Mod) :-
|
||||||
|
fail.
|
||||||
|
|
||||||
|
'$complete_goal'(M, G, CurMod, CurG, NG) :-
|
||||||
|
(
|
||||||
|
'$is_metapredicate'(CurG,CurMod)
|
||||||
|
->
|
||||||
|
'$meta_expansion'(G, M, CurMod, M, NG, [])
|
||||||
|
;
|
||||||
|
NG = G
|
||||||
|
).
|
||||||
|
|
||||||
|
/**
|
||||||
|
@}
|
||||||
|
*/
|
Reference in New Issue
Block a user