new builtins: nth_clause, nth_instance.
allow clause/3 on static predicates. predicate_property(P,number_of_clauses(N)). improve profiling code. git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@728 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
parent
f7161d37c4
commit
8b867ea4de
@ -1467,7 +1467,7 @@ p_number_of_clauses(void)
|
|||||||
ncl++;
|
ncl++;
|
||||||
}
|
}
|
||||||
READ_UNLOCK(RepPredProp(pe)->PRWLock);
|
READ_UNLOCK(RepPredProp(pe)->PRWLock);
|
||||||
t = MkIntTerm(ncl);
|
t = MkIntegerTerm(ncl);
|
||||||
return (Yap_unify_constant(ARG3, t));
|
return (Yap_unify_constant(ARG3, t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
224
C/dbase.c
224
C/dbase.c
@ -2067,10 +2067,10 @@ UnifyDBKey(DBRef DBSP, PropFlags flags, Term t)
|
|||||||
} else {
|
} else {
|
||||||
t1 = Yap_MkNewApplTerm(p->FunctorOfDB,p->ArityOfDB);
|
t1 = Yap_MkNewApplTerm(p->FunctorOfDB,p->ArityOfDB);
|
||||||
}
|
}
|
||||||
if (p->KindOfPE & CodeDBBit && (flags & CodeDBBit)) {
|
if ((p->KindOfPE & CodeDBBit) && (flags & CodeDBBit)) {
|
||||||
Term t[2];
|
Term t[2];
|
||||||
t[1] = Yap_LookupModule(p->ModuleOfDB);
|
t[0] = ModuleName[p->ModuleOfDB];
|
||||||
t[2] = t1;
|
t[1] = t1;
|
||||||
tf = Yap_MkApplTerm(FunctorModule, 2, t);
|
tf = Yap_MkApplTerm(FunctorModule, 2, t);
|
||||||
} else if (!(flags & CodeDBBit)) {
|
} else if (!(flags & CodeDBBit)) {
|
||||||
tf = t1;
|
tf = t1;
|
||||||
@ -2082,6 +2082,27 @@ UnifyDBKey(DBRef DBSP, PropFlags flags, Term t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
UnifyDBNumber(DBRef DBSP, Term t)
|
||||||
|
{
|
||||||
|
DBProp p = DBSP->Parent;
|
||||||
|
DBRef ref;
|
||||||
|
Int i = 1;
|
||||||
|
|
||||||
|
READ_LOCK(p->DBRWLock);
|
||||||
|
ref = p->First;
|
||||||
|
while (ref != NIL) {
|
||||||
|
if (ref == DBSP) break;
|
||||||
|
if (!DEAD_REF(ref)) i++;
|
||||||
|
ref = ref->Next;
|
||||||
|
}
|
||||||
|
if (ref == NIL)
|
||||||
|
return FALSE;
|
||||||
|
READ_UNLOCK(p->DBRWLock);
|
||||||
|
return(Yap_unify(MkIntegerTerm(i),t));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static Term
|
static Term
|
||||||
GetDBTerm(DBRef DBSP)
|
GetDBTerm(DBRef DBSP)
|
||||||
{
|
{
|
||||||
@ -2355,6 +2376,193 @@ FetchDBPropFromKey(Term twork, int flag, int new, char *error_mssg)
|
|||||||
return(RepDBProp(FindDBProp(RepAtom(At), flag, arity, dbmod)));
|
return(RepDBProp(FindDBProp(RepAtom(At), flag, arity, dbmod)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static DBRef
|
||||||
|
nth_recorded_log(LogUpdDBProp AtProp, Int Count)
|
||||||
|
{
|
||||||
|
DBRef ref;
|
||||||
|
|
||||||
|
if (AtProp->NOfEntries == 0) {
|
||||||
|
READ_UNLOCK(AtProp->DBRWLock);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (Count > AtProp->NOfEntries) {
|
||||||
|
READ_UNLOCK(AtProp->DBRWLock);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (AtProp->NOfEntries == 1) {
|
||||||
|
ref = AtProp->First;
|
||||||
|
} else {
|
||||||
|
if (AtProp->Index == NULL) {
|
||||||
|
while((AtProp->Index = new_lu_index(AtProp)) == NULL) {
|
||||||
|
if (!Yap_growheap(FALSE)) {
|
||||||
|
Yap_Error(SYSTEM_ERROR, TermNil, Yap_ErrorMessage);
|
||||||
|
READ_UNLOCK(AtProp->DBRWLock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ref = ((DBRef *)(AtProp->Index->Contents))[Count-1];
|
||||||
|
}
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Finds a term recorded under the key ARG1 */
|
||||||
|
static Int
|
||||||
|
nth_recorded(DBProp AtProp, Int Count)
|
||||||
|
{
|
||||||
|
Register DBRef ref;
|
||||||
|
|
||||||
|
READ_LOCK(AtProp->DBRWLock);
|
||||||
|
if (AtProp->KindOfPE & 0x1) {
|
||||||
|
ref = nth_recorded_log((LogUpdDBProp)AtProp, Count);
|
||||||
|
if (ref == NULL) {
|
||||||
|
READ_UNLOCK(AtProp->DBRWLock);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
#ifdef KEEP_OLD_ENTRIES_HANGING_ABOUT
|
||||||
|
ref = AtProp->FirstNEr;
|
||||||
|
#else
|
||||||
|
ref = AtProp->First;
|
||||||
|
#endif
|
||||||
|
Count--;
|
||||||
|
while (ref != NULL
|
||||||
|
&& DEAD_REF(ref))
|
||||||
|
ref = NextDBRef(ref);
|
||||||
|
if (ref == NULL) {
|
||||||
|
READ_UNLOCK(AtProp->DBRWLock);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
while (Count) {
|
||||||
|
Count--;
|
||||||
|
ref = NextDBRef(ref);
|
||||||
|
while (ref != NULL
|
||||||
|
&& DEAD_REF(ref))
|
||||||
|
ref = NextDBRef(ref);
|
||||||
|
if (ref == NULL) {
|
||||||
|
READ_UNLOCK(AtProp->DBRWLock);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if defined(YAPOR) || defined(THREADS)
|
||||||
|
LOCK(ref->lock);
|
||||||
|
READ_UNLOCK(AtProp->DBRWLock);
|
||||||
|
TRAIL_REF(ref); /* So that fail will erase it */
|
||||||
|
INC_DBREF_COUNT(ref);
|
||||||
|
UNLOCK(ref->lock);
|
||||||
|
#else
|
||||||
|
if (!(ref->Flags & InUseMask)) {
|
||||||
|
ref->Flags |= InUseMask;
|
||||||
|
TRAIL_REF(ref); /* So that fail will erase it */
|
||||||
|
}
|
||||||
|
READ_UNLOCK(AtProp->DBRWLock);
|
||||||
|
#endif
|
||||||
|
return Yap_unify(MkDBRefTerm(ref),ARG3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Int
|
||||||
|
p_nth_instance(void)
|
||||||
|
{
|
||||||
|
DBProp AtProp;
|
||||||
|
Term TCount;
|
||||||
|
Int Count;
|
||||||
|
Term t3 = Deref(ARG3);
|
||||||
|
|
||||||
|
if (!IsVarTerm(t3)) {
|
||||||
|
if (!IsDBRefTerm(t3)) {
|
||||||
|
Yap_Error(TYPE_ERROR_DBREF,t3,"nth_instance/3");
|
||||||
|
return FALSE;
|
||||||
|
} else {
|
||||||
|
DBRef ref = DBRefOfTerm(t3);
|
||||||
|
LOCK(ref->lock);
|
||||||
|
if (ref == NULL
|
||||||
|
|| DEAD_REF(ref)
|
||||||
|
|| !UnifyDBKey(ref,0,ARG1)
|
||||||
|
|| !UnifyDBNumber(ref,ARG2)) {
|
||||||
|
UNLOCK(ref->lock);
|
||||||
|
return(FALSE);
|
||||||
|
} else {
|
||||||
|
UNLOCK(ref->lock);
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (EndOfPAEntr(AtProp = FetchDBPropFromKey(Deref(ARG1), 0, FALSE, "nth_instance/3"))) {
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
TCount = Deref(ARG2);
|
||||||
|
if (IsVarTerm(TCount)) {
|
||||||
|
Yap_Error(INSTANTIATION_ERROR, TCount, "nth_instance/3");
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
if (!IsIntegerTerm(TCount)) {
|
||||||
|
Yap_Error(TYPE_ERROR_INTEGER, TCount, "nth_instance/3");
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
Count = IntegerOfTerm(TCount);
|
||||||
|
if (Count <= 0) {
|
||||||
|
if (Count)
|
||||||
|
Yap_Error(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, TCount, "nth_instance/3");
|
||||||
|
else
|
||||||
|
Yap_Error(DOMAIN_ERROR_NOT_ZERO, TCount, "nth_instance/3");
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
return nth_recorded(AtProp,Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Int
|
||||||
|
p_nth_instancep(void)
|
||||||
|
{
|
||||||
|
DBProp AtProp;
|
||||||
|
Term TCount;
|
||||||
|
Int Count;
|
||||||
|
Term t3 = Deref(ARG3);
|
||||||
|
|
||||||
|
if (!IsVarTerm(t3)) {
|
||||||
|
if (!IsDBRefTerm(t3)) {
|
||||||
|
Yap_Error(TYPE_ERROR_DBREF,t3,"nth_instance/3");
|
||||||
|
return FALSE;
|
||||||
|
} else {
|
||||||
|
DBRef ref = DBRefOfTerm(t3);
|
||||||
|
LOCK(ref->lock);
|
||||||
|
if (ref == NULL
|
||||||
|
|| DEAD_REF(ref)
|
||||||
|
|| !UnifyDBKey(ref,CodeDBBit,ARG1)
|
||||||
|
|| !UnifyDBNumber(ref,ARG2)) {
|
||||||
|
UNLOCK(ref->lock);
|
||||||
|
return(FALSE);
|
||||||
|
} else {
|
||||||
|
UNLOCK(ref->lock);
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (EndOfPAEntr(AtProp = FetchDBPropFromKey(Deref(ARG1), MkCode, FALSE, "nth_instance/3"))) {
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
TCount = Deref(ARG2);
|
||||||
|
if (IsVarTerm(TCount)) {
|
||||||
|
Yap_Error(INSTANTIATION_ERROR, TCount, "recorded_at/4");
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
if (!IsIntegerTerm(TCount)) {
|
||||||
|
Yap_Error(TYPE_ERROR_INTEGER, TCount, "recorded_at/4");
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
Count = IntegerOfTerm(TCount);
|
||||||
|
if (Count <= 0) {
|
||||||
|
if (Count)
|
||||||
|
Yap_Error(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, TCount, "recorded_at/4");
|
||||||
|
else
|
||||||
|
Yap_Error(DOMAIN_ERROR_NOT_ZERO, TCount, "recorded_at/4");
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
return nth_recorded(AtProp,Count);
|
||||||
|
}
|
||||||
|
|
||||||
/* Finds a term recorded under the key ARG1 */
|
/* Finds a term recorded under the key ARG1 */
|
||||||
static Int
|
static Int
|
||||||
i_log_upd_recorded(LogUpdDBProp AtProp)
|
i_log_upd_recorded(LogUpdDBProp AtProp)
|
||||||
@ -2378,10 +2586,10 @@ i_log_upd_recorded(LogUpdDBProp AtProp)
|
|||||||
rtable[0] = NIL;
|
rtable[0] = NIL;
|
||||||
} else {
|
} else {
|
||||||
if (AtProp->Index == NULL) {
|
if (AtProp->Index == NULL) {
|
||||||
if((AtProp->Index = new_lu_index(AtProp)) == NULL) {
|
while((AtProp->Index = new_lu_index(AtProp)) == NULL) {
|
||||||
if (!Yap_growheap(FALSE)) {
|
if (!Yap_growheap(FALSE)) {
|
||||||
Yap_Error(SYSTEM_ERROR, TermNil, Yap_ErrorMessage);
|
Yap_Error(SYSTEM_ERROR, TermNil, Yap_ErrorMessage);
|
||||||
cut_fail();
|
return FALSE;
|
||||||
}
|
}
|
||||||
twork = Deref(ARG2);
|
twork = Deref(ARG2);
|
||||||
}
|
}
|
||||||
@ -2478,7 +2686,7 @@ i_log_upd_recorded(LogUpdDBProp AtProp)
|
|||||||
TRef = MkDBRefTerm(ref);
|
TRef = MkDBRefTerm(ref);
|
||||||
if (*ep == NULL) {
|
if (*ep == NULL) {
|
||||||
if (Yap_unify(ARG3, TRef)) {
|
if (Yap_unify(ARG3, TRef)) {
|
||||||
#if defined(YAPOR) || defined(THREADS)
|
#if defined(OR) || defined(THREADS)
|
||||||
LOCK(ref->lock);
|
LOCK(ref->lock);
|
||||||
TRAIL_REF(ref); /* So that fail will erase it */
|
TRAIL_REF(ref); /* So that fail will erase it */
|
||||||
INC_DBREF_COUNT(ref);
|
INC_DBREF_COUNT(ref);
|
||||||
@ -3701,7 +3909,7 @@ EraseEntry(DBRef entryref)
|
|||||||
#endif /* DISCONNECT_OLD_ENTRIES */
|
#endif /* DISCONNECT_OLD_ENTRIES */
|
||||||
if (!DBREF_IN_USE(entryref)) {
|
if (!DBREF_IN_USE(entryref)) {
|
||||||
ErDBE(entryref);
|
ErDBE(entryref);
|
||||||
} else if ((entryref->Flags & DBCode) && entryref->Code) {
|
} else if ((entryref->Flags & DBCode && entryref->Code)) {
|
||||||
PrepareToEraseClause(ClauseCodeToClause(entryref->Code), entryref);
|
PrepareToEraseClause(ClauseCodeToClause(entryref->Code), entryref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4467,6 +4675,8 @@ Yap_InitDBPreds(void)
|
|||||||
Yap_InitCPred("$fetch_reference_from_index", 3, p_fetch_reference_from_index, SafePredFlag|SyncPredFlag);
|
Yap_InitCPred("$fetch_reference_from_index", 3, p_fetch_reference_from_index, SafePredFlag|SyncPredFlag);
|
||||||
Yap_InitCPred("$resize_int_keys", 1, p_resize_int_keys, SafePredFlag|SyncPredFlag);
|
Yap_InitCPred("$resize_int_keys", 1, p_resize_int_keys, SafePredFlag|SyncPredFlag);
|
||||||
Yap_InitCPred("key_statistics", 3, p_key_statistics, SyncPredFlag);
|
Yap_InitCPred("key_statistics", 3, p_key_statistics, SyncPredFlag);
|
||||||
|
Yap_InitCPred("nth_instance", 3, p_nth_instance, SyncPredFlag);
|
||||||
|
Yap_InitCPred("$nth_instancep", 3, p_nth_instancep, SyncPredFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
66
docs/yap.tex
66
docs/yap.tex
@ -4744,7 +4744,25 @@ program. Its head and body are respectively unified with @var{H} and
|
|||||||
@var{true}.
|
@var{true}.
|
||||||
|
|
||||||
This predicate is applicable to static procedures compiled with
|
This predicate is applicable to static procedures compiled with
|
||||||
@code{source} active, and to all the dynamic procedures.
|
@code{source} active, and to all dynamic procedures.
|
||||||
|
|
||||||
|
@item clause(+@var{H},@var{B},-@var{R})
|
||||||
|
@findex clause/3
|
||||||
|
@saindex clause/3
|
||||||
|
@caindex clause/3
|
||||||
|
The same as @code{clause/2}, plus @var{R} is unified with the
|
||||||
|
reference to the clause in the database. You can use @code{instance/2}
|
||||||
|
to access the reference's value. Note that you may not use
|
||||||
|
@code{erase/1} on the reference on static procedures.
|
||||||
|
|
||||||
|
@item nth_clause(+@var{H},@var{I},-@var{R})
|
||||||
|
@findex nth_clause/3
|
||||||
|
@saindex nth_clause/3
|
||||||
|
@caindex nth_clause/3
|
||||||
|
Find the @var{I}th clause in the predicate defining @var{H}, and give
|
||||||
|
a reference to the clause. Alternatively, if the reference @var{R} is
|
||||||
|
given the head @var{H} is unified with a description of the predicate
|
||||||
|
and @var{I} is bound to its position.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@ -4856,6 +4874,9 @@ true if the predicate is public; note that all dynamic predicates are
|
|||||||
public.
|
public.
|
||||||
@item source
|
@item source
|
||||||
true if source for the predicate is available.
|
true if source for the predicate is available.
|
||||||
|
@item number_of_clauses(@var{ClauseCount})
|
||||||
|
Number of clauses in the predicate definition. Always one if external
|
||||||
|
or built-in.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
@ -4904,16 +4925,9 @@ declared dynamic.
|
|||||||
@saindex retract/2
|
@saindex retract/2
|
||||||
@caindex retract/2
|
@caindex retract/2
|
||||||
Erases from the program the clause @var{C} whose
|
Erases from the program the clause @var{C} whose
|
||||||
database reference is @var{R}.
|
database reference is @var{R}. The predicate must be dynamic.
|
||||||
|
|
||||||
|
|
||||||
@item clause(+H,B,-@var{R})
|
|
||||||
@findex clause/3
|
|
||||||
@saindex clause/3
|
|
||||||
@caindex clause/3
|
|
||||||
The same as @code{clause(H,B)} but @var{R} is unified with the
|
|
||||||
reference to the clause in the database.
|
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@node Internal Database, BlackBoard, Database References, Database
|
@node Internal Database, BlackBoard, Database References, Database
|
||||||
@ -4977,6 +4991,16 @@ elements of the internal data-base that match the key.
|
|||||||
match the reference.
|
match the reference.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
|
@item nth_instance(?@var{K},?@var{Index},@var{T},?@var{R})
|
||||||
|
@findex nth_recorded/3
|
||||||
|
@saindex nth_recorded/3
|
||||||
|
@cnindex nth_recorded/3
|
||||||
|
Fetches the @var{Index}nth entry in the internal database under the
|
||||||
|
key @var{K}. Entries are numbered from one. If the key @var{K} are the
|
||||||
|
@var{Index} are bound, a reference is unified with @var{R}. Otherwise,
|
||||||
|
the reference @var{R} must be given, and the term the system will find
|
||||||
|
the matching key and index.
|
||||||
|
|
||||||
@item erase(+@var{R})
|
@item erase(+@var{R})
|
||||||
@findex erase/1
|
@findex erase/1
|
||||||
@saindex erase/1
|
@saindex erase/1
|
||||||
@ -5671,31 +5695,30 @@ newer implementation.
|
|||||||
@item Currently only information on entries and retries to a predicate
|
@item Currently only information on entries and retries to a predicate
|
||||||
are maintained. This may change in the future.
|
are maintained. This may change in the future.
|
||||||
@item As an example, the following user-level program gives a list of
|
@item As an example, the following user-level program gives a list of
|
||||||
the most often called procedures in a program:
|
the most often called procedures in a program. The procedure
|
||||||
|
@code{list_profile} shows all procedures, irrespective of module, and
|
||||||
|
the procedure @code{list_profile/1} shows the procedures being used in
|
||||||
|
a specific module.
|
||||||
@example
|
@example
|
||||||
list_profile :-
|
list_profile :-
|
||||||
% get number of calls for each profiled procedure
|
% get number of calls for each profiled procedure
|
||||||
findall(D-P,profile_data(P,calls,D),LP),
|
setof(D-[M:P|D1],(current_module(M),profile_data(M:P,calls,D),profile_data(M:P,retries,D1)),LP),
|
||||||
% sort them
|
|
||||||
sort(LP,SLP),
|
|
||||||
% output so that the most often called
|
% output so that the most often called
|
||||||
% predicates will come last:
|
% predicates will come last:
|
||||||
write_profile_data(SLP).
|
write_profile_data(LP).
|
||||||
|
|
||||||
list_profile(Module) :-
|
list_profile(Module) :-
|
||||||
% get number of calls for each profiled procedure
|
% get number of calls for each profiled procedure
|
||||||
findall(D-P,profile_data(Module:P,calls,D),LP),
|
setof(D-[Module:P|D1],(profile_data(Module:P,calls,D),profile_data(Module:P,retries,D1)),LP),
|
||||||
% sort them
|
|
||||||
sort(LP,SLP),
|
|
||||||
% output so that the most often called
|
% output so that the most often called
|
||||||
% predicates will come last:
|
% predicates will come last:
|
||||||
write_profile_data(SLP).
|
write_profile_data(LP).
|
||||||
|
|
||||||
write_profile_data([]).
|
write_profile_data([]).
|
||||||
write_profile_data([D-P|SLP]) :-
|
write_profile_data([D-[M:P|R]|SLP]) :-
|
||||||
% swap the two calls if you want the most often
|
% swap the two calls if you want the most often
|
||||||
% called predicates first.
|
% called predicates first.
|
||||||
format('~w: ~w~n', [P,D]),
|
format('~a:~w: ~32+~t~d~12+~t~d~12+~n', [M,P,D,R]),
|
||||||
write_profile_data(SLP).
|
write_profile_data(SLP).
|
||||||
@end example
|
@end example
|
||||||
@end itemize
|
@end itemize
|
||||||
@ -13631,9 +13654,6 @@ Prolog implements Unix-like escape sequences.
|
|||||||
standard. Use @code{prolog_initialization/1} for the SICStus Prolog
|
standard. Use @code{prolog_initialization/1} for the SICStus Prolog
|
||||||
compatible built-in.
|
compatible built-in.
|
||||||
|
|
||||||
@item YAP does not implement the tabbing primitives in
|
|
||||||
@code{format/2} and @code{format/3}.
|
|
||||||
|
|
||||||
@item Prolog flags are different in SICStus Prolog and in YAP.
|
@item Prolog flags are different in SICStus Prolog and in YAP.
|
||||||
|
|
||||||
@item The SICStus Prolog @code{on_exception/3} and
|
@item The SICStus Prolog @code{on_exception/3} and
|
||||||
|
27
pl/debug.yap
27
pl/debug.yap
@ -521,7 +521,8 @@ debugging :-
|
|||||||
('$undefined'('$set_depth_limit'(_),prolog) -> true ; '$set_depth_limit'(D)),
|
('$undefined'('$set_depth_limit'(_),prolog) -> true ; '$set_depth_limit'(D)),
|
||||||
CP is '$last_choice_pt',
|
CP is '$last_choice_pt',
|
||||||
(
|
(
|
||||||
'$fetch_clause'(G,M,Cl,Clause),
|
'$nth_instancep'(M:G,Cl,R),
|
||||||
|
instance(R,(G:-Clause)),
|
||||||
(Clause = true -> true ; '$call'(Clause,CP,Clause,M) )
|
(Clause = true -> true ; '$call'(Clause,CP,Clause,M) )
|
||||||
;
|
;
|
||||||
Next is Cl+1, '$set_value'(spy_cl,Next), fail
|
Next is Cl+1, '$set_value'(spy_cl,Next), fail
|
||||||
@ -576,8 +577,13 @@ debugging :-
|
|||||||
('$undefined'('$set_depth_limit'(_),prolog) -> true ; '$set_depth_limit'(D)),
|
('$undefined'('$set_depth_limit'(_),prolog) -> true ; '$set_depth_limit'(D)),
|
||||||
CP is '$last_choice_pt',
|
CP is '$last_choice_pt',
|
||||||
(
|
(
|
||||||
'$fetch_clause'(G,M,Cl,Clause),
|
'$nth_instancep'(M:G,Cl,R),
|
||||||
(Clause = true -> true ;
|
instance(R,(G:-Clause)),
|
||||||
|
(
|
||||||
|
Clause = true
|
||||||
|
->
|
||||||
|
true
|
||||||
|
;
|
||||||
'$creep_call'(Clause,M,CP)
|
'$creep_call'(Clause,M,CP)
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
@ -638,21 +644,6 @@ debugging :-
|
|||||||
'$creep',
|
'$creep',
|
||||||
'$execute'(G,M,Cl).
|
'$execute'(G,M,Cl).
|
||||||
|
|
||||||
'$fetch_clause'(G,M,ClNum,Body) :-
|
|
||||||
% I'd like an easier way to keep a counter
|
|
||||||
'$set_value'('$fetching_clauses',1),
|
|
||||||
'$recordedp'(M:G,Clause,_),
|
|
||||||
'$get_value'('$fetching_clauses',Num),
|
|
||||||
( Num = ClNum ->
|
|
||||||
!,
|
|
||||||
Clause = (G :- Body)
|
|
||||||
;
|
|
||||||
Num1 is Num+1,
|
|
||||||
'$set_value'('$fetching_clauses',Num1),
|
|
||||||
fail
|
|
||||||
).
|
|
||||||
|
|
||||||
|
|
||||||
%'$creep_call'(G,_) :- write(user_error,'$creepcall'(G)), nl(user_error), fail.
|
%'$creep_call'(G,_) :- write(user_error,'$creepcall'(G)), nl(user_error), fail.
|
||||||
'$creep_call'(V,M,_) :- var(V), !,
|
'$creep_call'(V,M,_) :- var(V), !,
|
||||||
'$do_error'(instantiation_error,meta_call(M:V)).
|
'$do_error'(instantiation_error,meta_call(M:V)).
|
||||||
|
124
pl/preds.yap
124
pl/preds.yap
@ -230,30 +230,10 @@ assert(C,R) :-
|
|||||||
'$assert_dynamic'(C,M,last,R,assert(C,R)).
|
'$assert_dynamic'(C,M,last,R,assert(C,R)).
|
||||||
|
|
||||||
clause(M:P,Q) :- !,
|
clause(M:P,Q) :- !,
|
||||||
'$clause'(P,M,Q).
|
'$clause'(P,M,Q,_).
|
||||||
clause(V,Q) :-
|
clause(V,Q) :-
|
||||||
'$current_module'(M),
|
'$current_module'(M),
|
||||||
'$clause'(V,M,Q).
|
'$clause'(V,M,Q,R).
|
||||||
|
|
||||||
'$clause'(V,M,Q) :- var(V), !,
|
|
||||||
'$do_error'(instantiation_error,M:clause(V,Q)).
|
|
||||||
'$clause'(C,M,Q) :- number(C), !,
|
|
||||||
'$do_error'(type_error(callable,C),M:clause(C,Q)).
|
|
||||||
'$clause'(R,M,Q) :- db_reference(R), !,
|
|
||||||
'$do_error'(type_error(callable,R),M:clause(R,Q)).
|
|
||||||
'$clause'(M:P,_,Q) :- !,
|
|
||||||
'$clause'(P,M,Q).
|
|
||||||
'$clause'(P,Mod,Q) :- '$is_dynamic'(P, Mod), !,
|
|
||||||
'$recordedp'(Mod:P,(P:-Q),_).
|
|
||||||
'$clause'(P,M,Q) :-
|
|
||||||
'$some_recordedp'(M:P), !,
|
|
||||||
'$recordedp'(M:P,(P:-Q),_).
|
|
||||||
'$clause'(P,M,Q) :-
|
|
||||||
( '$system_predicate'(P,M) -> true ;
|
|
||||||
'$number_of_clauses'(P,M,N), N > 0 ),
|
|
||||||
functor(P,Name,Arity),
|
|
||||||
'$do_error'(permission_error(access,private_procedure,Name/Arity),
|
|
||||||
clause(M:P,Q)).
|
|
||||||
|
|
||||||
clause(M:P,Q,R) :- !,
|
clause(M:P,Q,R) :- !,
|
||||||
'$clause'(P,M,Q,R).
|
'$clause'(P,M,Q,R).
|
||||||
@ -261,6 +241,51 @@ clause(V,Q,R) :-
|
|||||||
'$current_module'(M),
|
'$current_module'(M),
|
||||||
'$clause'(V,M,Q,R).
|
'$clause'(V,M,Q,R).
|
||||||
|
|
||||||
|
'$clause'(V,M,Q,_) :- var(V), !,
|
||||||
|
'$do_error'(instantiation_error,M:clause(V,Q)).
|
||||||
|
'$clause'(C,M,Q,_) :- number(C), !,
|
||||||
|
'$do_error'(type_error(callable,C),M:clause(C,Q)).
|
||||||
|
'$clause'(R,M,Q,_) :- db_reference(R), !,
|
||||||
|
'$do_error'(type_error(callable,R),M:clause(R,Q)).
|
||||||
|
'$clause'(M:P,_,Q,R) :- !,
|
||||||
|
'$clause'(P,M,Q,R).
|
||||||
|
'$clause'(P,M,Q,R) :-
|
||||||
|
'$some_recordedp'(M:P), !,
|
||||||
|
'$recordedp'(M:P,(P:-Q),R).
|
||||||
|
'$clause'(P,M,Q,_) :-
|
||||||
|
( '$system_predicate'(P,M) -> true ;
|
||||||
|
'$number_of_clauses'(P,M,N), N > 0 ),
|
||||||
|
functor(P,Name,Arity),
|
||||||
|
'$do_error'(permission_error(access,private_procedure,Name/Arity),
|
||||||
|
clause(M:P,Q)).
|
||||||
|
|
||||||
|
nth_clause(P,I,R) :- nonvar(R), !,
|
||||||
|
'$nth_instancep'(P,I,R).
|
||||||
|
nth_clause(M:V,I,R) :- !,
|
||||||
|
'$nth_clause'(V,M,I,R).
|
||||||
|
nth_clause(V,I,R) :-
|
||||||
|
'$current_module'(M),
|
||||||
|
'$nth_clause'(V,M,I,R).
|
||||||
|
|
||||||
|
|
||||||
|
'$nth_clause'(V,M,I,R) :- var(V), !,
|
||||||
|
'$do_error'(instantiation_error,M:nth_clause(V,I,R)).
|
||||||
|
'$nth_clause'(C,M,I,R) :- number(C), !,
|
||||||
|
'$do_error'(type_error(callable,C),M:nth_clause(C,I,R)).
|
||||||
|
'$nth_clause'(R,M,I,R) :- db_reference(R), !,
|
||||||
|
'$do_error'(type_error(callable,R),M:nth_clause(R,I,R)).
|
||||||
|
'$nth_clause'(M:P,_,I,R) :- !,
|
||||||
|
'$nth_clause'(P,M,I,R).
|
||||||
|
'$nth_clause'(P,M,I,R) :-
|
||||||
|
'$some_recordedp'(M:P), !,
|
||||||
|
'$nth_instancep'(M:P,I,R).
|
||||||
|
'$nth_clause'(P,M,I,R) :-
|
||||||
|
( '$system_predicate'(P,M) -> true ;
|
||||||
|
'$number_of_nth_clauses'(P,M,N), N > 0 ),
|
||||||
|
functor(P,Name,Arity),
|
||||||
|
'$do_error'(permission_error(access,private_procedure,Name/Arity),
|
||||||
|
nth_clause(M:P,I,R)).
|
||||||
|
|
||||||
'$clause'(V,M,Q,R) :- var(V), !,
|
'$clause'(V,M,Q,R) :- var(V), !,
|
||||||
'$do_error'(instantiation_error,M:clause(V,Q,R)).
|
'$do_error'(instantiation_error,M:clause(V,Q,R)).
|
||||||
'$clause'(C,M,Q,R) :- number(C), !,
|
'$clause'(C,M,Q,R) :- number(C), !,
|
||||||
@ -635,8 +660,63 @@ hide_predicate(P) :-
|
|||||||
NF is F \/ 0x8200000,
|
NF is F \/ 0x8200000,
|
||||||
'$flags'(P,prolog,F,NF).
|
'$flags'(P,prolog,F,NF).
|
||||||
|
|
||||||
|
predicate_property(Mod:Pred,Prop) :- !,
|
||||||
|
'$predicate_property2'(Pred,Prop,Mod).
|
||||||
|
predicate_property(Pred,Prop) :-
|
||||||
|
'$current_module'(Mod),
|
||||||
|
'$predicate_property2'(Pred,Prop,Mod).
|
||||||
|
|
||||||
|
'$predicate_property2'(Pred,Prop,M) :- var(Pred), !,
|
||||||
|
'$generate_all_preds_from_mod'(Pred, SourceMod, M),
|
||||||
|
'$predicate_property'(Pred,SourceMod,M,Prop).
|
||||||
|
'$predicate_property2'(M:Pred,Prop,_) :- !,
|
||||||
|
'$predicate_property2'(Pred,Prop,M).
|
||||||
|
'$predicate_property2'(Pred,Prop,Mod) :-
|
||||||
|
'$pred_exists'(Pred,Mod), !,
|
||||||
|
'$predicate_property'(Pred,Mod,Mod,Prop).
|
||||||
|
'$predicate_property2'(Pred,Prop,Mod) :-
|
||||||
|
functor(Pred, N, K),
|
||||||
|
'$recorded'('$import','$import'(M,Mod,N,K),_),
|
||||||
|
'$predicate_property'(Pred,M,Mod,Prop).
|
||||||
|
|
||||||
|
'$generate_all_preds_from_mod'(Pred, M, M) :-
|
||||||
|
'$current_predicate'(M,Na,Ar),
|
||||||
|
functor(Pred, Na, Ar).
|
||||||
|
'$generate_all_preds_from_mod'(Pred, SourceMod, Mod) :-
|
||||||
|
'$recorded'('$import','$import'(SourceMod,Mod,N,K),_),
|
||||||
|
functor(Pred, N, K).
|
||||||
|
|
||||||
|
|
||||||
|
'$predicate_property'(P,M,_,built_in) :-
|
||||||
|
'$system_predicate'(P,M), !.
|
||||||
|
'$predicate_property'(P,M,_,source) :-
|
||||||
|
( '$recordedp'(M:P,_,_) -> true ; false).
|
||||||
|
'$predicate_property'(P,M,_,dynamic) :-
|
||||||
|
'$is_dynamic'(P,M).
|
||||||
|
'$predicate_property'(P,M,_,static) :-
|
||||||
|
\+ '$is_dynamic'(P,M),
|
||||||
|
\+ '$undefined'(P,M).
|
||||||
|
'$predicate_property'(P,M,_,meta_predicate(P)) :-
|
||||||
|
functor(P,Na,Ar),
|
||||||
|
'$meta_predicate'(M,Na,Ar,P).
|
||||||
|
'$predicate_property'(P,M,_,multifile) :-
|
||||||
|
'$is_multifile'(P,M).
|
||||||
|
'$predicate_property'(P,Mod,M,imported_from(Mod)) :-
|
||||||
|
functor(P,N,K),
|
||||||
|
'$recorded'('$import','$import'(Mod,M,N,K),_).
|
||||||
|
'$predicate_property'(P,M,_,public) :-
|
||||||
|
'$is_public'(P,M).
|
||||||
|
'$predicate_property'(P,M,M,exported) :-
|
||||||
|
functor(P,N,A),
|
||||||
|
'$recorded'('$module','$module'(_TFN,M,Publics),_),
|
||||||
|
'$member'(N/A,Publics), !. /* defined in modules.yap */
|
||||||
|
'$predicate_property'(P,Mod,_,number_of_clauses(NCl)) :-
|
||||||
|
'$number_of_clauses'(P,Mod,NCl).
|
||||||
|
|
||||||
|
|
||||||
:- '$make_pred_push_mod'((_,_)).
|
:- '$make_pred_push_mod'((_,_)).
|
||||||
:- '$make_pred_push_mod'((_;_)).
|
:- '$make_pred_push_mod'((_;_)).
|
||||||
:- '$make_pred_push_mod'((_|_)).
|
:- '$make_pred_push_mod'((_|_)).
|
||||||
:- '$make_pred_push_mod'((_->_)).
|
:- '$make_pred_push_mod'((_->_)).
|
||||||
:- '$make_pred_push_mod'((\+_)).
|
:- '$make_pred_push_mod'((\+_)).
|
||||||
|
|
||||||
|
@ -46,8 +46,6 @@ profile_data(P, Parm, Data) :-
|
|||||||
'$profile_info'(M, P, Stats),
|
'$profile_info'(M, P, Stats),
|
||||||
'$profile_say'(Stats, Parm, Data).
|
'$profile_say'(Stats, Parm, Data).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
'$profile_say'('$profile'(Entries, _, _), calls, Entries).
|
'$profile_say'('$profile'(Entries, _, _), calls, Entries).
|
||||||
'$profile_say'('$profile'(_, _, Backtracks), retries, Backtracks).
|
'$profile_say'('$profile'(_, _, Backtracks), retries, Backtracks).
|
||||||
|
|
||||||
|
51
pl/utils.yap
51
pl/utils.yap
@ -540,57 +540,6 @@ unknown(V0,V) :-
|
|||||||
[P,M,Na,Ar]),
|
[P,M,Na,Ar]),
|
||||||
fail.
|
fail.
|
||||||
|
|
||||||
predicate_property(Mod:Pred,Prop) :- !,
|
|
||||||
'$predicate_property2'(Pred,Prop,Mod).
|
|
||||||
predicate_property(Pred,Prop) :-
|
|
||||||
'$current_module'(Mod),
|
|
||||||
'$predicate_property2'(Pred,Prop,Mod).
|
|
||||||
|
|
||||||
'$predicate_property2'(Pred,Prop,M) :- var(Pred), !,
|
|
||||||
'$generate_all_preds_from_mod'(Pred, SourceMod, M),
|
|
||||||
'$predicate_property'(Pred,SourceMod,M,Prop).
|
|
||||||
'$predicate_property2'(M:Pred,Prop,_) :- !,
|
|
||||||
'$predicate_property2'(Pred,Prop,M).
|
|
||||||
'$predicate_property2'(Pred,Prop,Mod) :-
|
|
||||||
'$pred_exists'(Pred,Mod), !,
|
|
||||||
'$predicate_property'(Pred,Mod,Mod,Prop).
|
|
||||||
'$predicate_property2'(Pred,Prop,Mod) :-
|
|
||||||
functor(Pred, N, K),
|
|
||||||
'$recorded'('$import','$import'(M,Mod,N,K),_),
|
|
||||||
'$predicate_property'(Pred,M,Mod,Prop).
|
|
||||||
|
|
||||||
'$generate_all_preds_from_mod'(Pred, M, M) :-
|
|
||||||
'$current_predicate'(M,Na,Ar),
|
|
||||||
functor(Pred, Na, Ar).
|
|
||||||
'$generate_all_preds_from_mod'(Pred, SourceMod, Mod) :-
|
|
||||||
'$recorded'('$import','$import'(SourceMod,Mod,N,K),_),
|
|
||||||
functor(Pred, N, K).
|
|
||||||
|
|
||||||
|
|
||||||
'$predicate_property'(P,M,_,built_in) :-
|
|
||||||
'$system_predicate'(P,M), !.
|
|
||||||
'$predicate_property'(P,M,_,source) :-
|
|
||||||
( '$recordedp'(M:P,_,_) -> true ; false).
|
|
||||||
'$predicate_property'(P,M,_,dynamic) :-
|
|
||||||
'$is_dynamic'(P,M).
|
|
||||||
'$predicate_property'(P,M,_,static) :-
|
|
||||||
\+ '$is_dynamic'(P,M),
|
|
||||||
\+ '$undefined'(P,M).
|
|
||||||
'$predicate_property'(P,M,_,meta_predicate(P)) :-
|
|
||||||
functor(P,Na,Ar),
|
|
||||||
'$meta_predicate'(M,Na,Ar,P).
|
|
||||||
'$predicate_property'(P,M,_,multifile) :-
|
|
||||||
'$is_multifile'(P,M).
|
|
||||||
'$predicate_property'(P,Mod,M,imported_from(Mod)) :-
|
|
||||||
functor(P,N,K),
|
|
||||||
'$recorded'('$import','$import'(Mod,M,N,K),_).
|
|
||||||
'$predicate_property'(P,M,_,public) :-
|
|
||||||
'$is_public'(P,M).
|
|
||||||
'$predicate_property'(P,M,M,exported) :-
|
|
||||||
functor(P,N,A),
|
|
||||||
'$recorded'('$module','$module'(_TFN,M,Publics),_),
|
|
||||||
'$member'(N/A,Publics), !. /* defined in modules.yap */
|
|
||||||
|
|
||||||
%%% Some "dirty" predicates
|
%%% Some "dirty" predicates
|
||||||
|
|
||||||
% Only efective if yap compiled with -DDEBUG
|
% Only efective if yap compiled with -DDEBUG
|
||||||
|
Reference in New Issue
Block a user