fix predicate search
This commit is contained in:
parent
2ad3420fac
commit
f1ddb5822e
@ -834,7 +834,7 @@ Prop Yap_PredPropByFunctorNonThreadLocal(Functor f, Term cur_mod)
|
||||
|
||||
if ((p->ModuleOfPred == cur_mod || !(p->ModuleOfPred))) {
|
||||
/* don't match multi-files */
|
||||
if (!(p->PredFlags & MultiFileFlag) || p->ModuleOfPred || !cur_mod ||
|
||||
if (/*!(p->PredFlags & MultiFileFlag) ||*/ true || p->ModuleOfPred || !cur_mod ||
|
||||
cur_mod == TermProlog) {
|
||||
FUNC_WRITE_UNLOCK(f);
|
||||
return AbsPredProp(p);
|
||||
@ -871,7 +871,7 @@ Prop Yap_PredPropByAtomNonThreadLocal(Atom at, Term cur_mod)
|
||||
if (pe->KindOfPE == PEProp &&
|
||||
(pe->ModuleOfPred == cur_mod || !pe->ModuleOfPred)) {
|
||||
/* don't match multi-files */
|
||||
if (!(pe->PredFlags & MultiFileFlag) || pe->ModuleOfPred || !cur_mod ||
|
||||
if (/*!(pe->PredFlags & MultiFileFlag) ||*/ true || pe->ModuleOfPred || !cur_mod ||
|
||||
cur_mod == TermProlog) {
|
||||
WRITE_UNLOCK(ae->ARWLock);
|
||||
return (p0);
|
||||
|
33
C/cdmgr.c
33
C/cdmgr.c
@ -1019,7 +1019,7 @@ static void retract_all(PredEntry *p, int in_use) {
|
||||
}
|
||||
p->cs.p_code.FirstClause = NULL;
|
||||
p->cs.p_code.LastClause = NULL;
|
||||
if (p->PredFlags & (DynamicPredFlag | LogUpdatePredFlag | MultiFileFlag)) {
|
||||
if (is_live(p)) {
|
||||
p->OpcodeOfPred = FAIL_OPCODE;
|
||||
} else {
|
||||
p->OpcodeOfPred = UNDEF_OPCODE;
|
||||
@ -1742,8 +1742,9 @@ bool Yap_addclause(Term t, yamop *cp, Term tmode, Term mod, Term *t4ref)
|
||||
if (pflags & IndexedPredFlag) {
|
||||
Yap_AddClauseToIndex(p, cp, mode == asserta);
|
||||
}
|
||||
if (pflags & (SpiedPredFlag | CountPredFlag | ProfiledPredFlag))
|
||||
if (pflags & (SpiedPredFlag | CountPredFlag | ProfiledPredFlag)) {
|
||||
spy_flag = true;
|
||||
}
|
||||
if (Yap_discontiguous(p, tmode PASS_REGS)) {
|
||||
Term disc[3], sc[4];
|
||||
if (p->ArityOfPE) {
|
||||
@ -1914,7 +1915,7 @@ void Yap_EraseStaticClause(StaticClause *cl, PredEntry *ap, Term mod) {
|
||||
if (ap->cs.p_code.LastClause == cl->ClCode) {
|
||||
/* got rid of all clauses */
|
||||
ap->cs.p_code.LastClause = ap->cs.p_code.FirstClause = NULL;
|
||||
if (!(ap->PredFlags & MultiFileFlag)) {
|
||||
if (is_live(ap)) {
|
||||
ap->OpcodeOfPred = FAIL_OPCODE;
|
||||
} else {
|
||||
ap->OpcodeOfPred = UNDEF_OPCODE;
|
||||
@ -2434,23 +2435,21 @@ static Int p_new_multifile(USES_REGS1) { /* '$new_multifile'(+N,+Ar,+Mod) */
|
||||
else
|
||||
pe = RepPredProp(PredPropByFunc(Yap_MkFunctor(at, arity), mod));
|
||||
PELOCK(26, pe);
|
||||
if (pe->PredFlags &
|
||||
(UserCPredFlag | CArgsPredFlag | NumberDBPredFlag | AtomDBPredFlag |
|
||||
TestPredFlag | AsmPredFlag | CPredFlag | BinaryPredFlag)) {
|
||||
UNLOCKPE(26, pe);
|
||||
addcl_permission_error(RepAtom(at), arity, FALSE);
|
||||
return false;
|
||||
}
|
||||
pe->PredFlags &= ~UndefPredFlag;
|
||||
if (pe->PredFlags & MultiFileFlag) {
|
||||
UNLOCKPE(26, pe);
|
||||
return true;
|
||||
}
|
||||
if (pe->PredFlags & (TabledPredFlag|ForeignPredFlags)) {
|
||||
UNLOCKPE(26, pe);
|
||||
addcl_permission_error(RepAtom(at), arity, FALSE);
|
||||
return false;
|
||||
}
|
||||
if (pe->cs.p_code.NOfClauses) {
|
||||
UNLOCKPE(26, pe);
|
||||
addcl_permission_error(RepAtom(at), arity, FALSE);
|
||||
return false;
|
||||
}
|
||||
pe->PredFlags &= ~UndefPredFlag;
|
||||
pe->PredFlags |= MultiFileFlag;
|
||||
/* mutifile-predicates are weird, they do not seat really on the default
|
||||
* module */
|
||||
@ -2727,7 +2726,7 @@ static Int p_pred_exists(USES_REGS1) { /* '$pred_exists'(+P,+M) */
|
||||
UNLOCKPE(54, pe);
|
||||
return false;
|
||||
}
|
||||
out = (pe->OpcodeOfPred != UNDEF_OPCODE);
|
||||
out = (is_live(pe) || pe->OpcodeOfPred != UNDEF_OPCODE);
|
||||
UNLOCKPE(55, pe);
|
||||
return out;
|
||||
}
|
||||
@ -2786,8 +2785,7 @@ static Int undefp_handler(USES_REGS1) { /* '$undefp_handler'(P,Mod) */
|
||||
if (EndOfPAEntr(pe))
|
||||
return false;
|
||||
PELOCK(59, pe);
|
||||
if (pe->OpcodeOfPred == UNDEF_OPCODE &&
|
||||
!(pe->PredFlags & (LogUpdatePredFlag|DynamicPredFlag|MultiFileFlag))) {
|
||||
if (pe->OpcodeOfPred == UNDEF_OPCODE) {
|
||||
UNLOCKPE(59, pe);
|
||||
return false;
|
||||
}
|
||||
@ -2803,12 +2801,7 @@ static Int p_undefined(USES_REGS1) { /* '$undefined'(P,Mod) */
|
||||
if (EndOfPAEntr(pe))
|
||||
return TRUE;
|
||||
PELOCK(36, pe);
|
||||
if (pe->PredFlags & (CPredFlag | UserCPredFlag | TestPredFlag | AsmPredFlag |MultiFileFlag|
|
||||
DynamicPredFlag | LogUpdatePredFlag | TabledPredFlag)) {
|
||||
UNLOCKPE(57, pe);
|
||||
return FALSE;
|
||||
}
|
||||
if (pe->OpcodeOfPred == UNDEF_OPCODE) {
|
||||
if (!is_live(pe) && pe->OpcodeOfPred == UNDEF_OPCODE) {
|
||||
UNLOCKPE(58, pe);
|
||||
return TRUE;
|
||||
}
|
||||
|
2
C/exec.c
2
C/exec.c
@ -2108,7 +2108,7 @@ static Int jump_env(USES_REGS1) {
|
||||
Yap_find_prolog_culprit(PASS_REGS1);
|
||||
// LOCAL_Error_TYPE = ERROR_EVENT;
|
||||
Term t1 = ArgOfTerm(1, t);
|
||||
if (IsApplTerm(t) && IsAtomTerm((t2 = ArgOfTerm(1, t1)))) {
|
||||
if (IsApplTerm(t1) && IsAtomTerm((t2 = ArgOfTerm(1, t1)))) {
|
||||
LOCAL_ActiveError->errorAsText = AtomOfTerm(t2);
|
||||
LOCAL_ActiveError->classAsText = NameOfFunctor(FunctorOfTerm(t1));
|
||||
} else if (IsAtomTerm(t)) {
|
||||
|
@ -487,10 +487,9 @@ bool YAPEngine::mgoal(Term t, Term tmod)
|
||||
if (ap == nullptr || ap->OpcodeOfPred == UNDEF_OPCODE)
|
||||
{
|
||||
ap = rewriteUndefEngineQuery(ap, t, tmod);
|
||||
}
|
||||
if (ap==nullptr)
|
||||
|
||||
if (ap == nullptr || ap->OpcodeOfPred == UNDEF_OPCODE)
|
||||
return false;
|
||||
} else
|
||||
{
|
||||
/* legal ap */
|
||||
arity_t arity = ap->ArityOfPE;
|
||||
|
@ -487,6 +487,8 @@ typedef uint64_t pred_flags_t;
|
||||
#define ForeignPredFlags \
|
||||
(AsmPredFlag | SWIEnvPredFlag | CPredFlag | BinaryPredFlag | UDIPredFlag | \
|
||||
CArgsPredFlag | UserCPredFlag | SafePredFlag | BackCPredFlag)
|
||||
#define LivePredFlags \
|
||||
(LogUpdatePredFlag|MultiFileFlag|TabledPredFlag|ForeignPredFlags)
|
||||
|
||||
#define StatePredFlags \
|
||||
(InUsePredFlag | CountPredFlag | SpiedPredFlag | IndexedPredFlag)
|
||||
@ -495,6 +497,7 @@ typedef uint64_t pred_flags_t;
|
||||
#define is_foreign(pe) (pe->PredFlags & ForeignPredFlags)
|
||||
#define is_static(pe) (pe->PredFlags & CompiledPredFlag)
|
||||
#define is_logupd(pe) (pe->PredFlags & LogUpdatePredFlag)
|
||||
#define is_live(pe) (pe->PredFlags & LivePredFlags)
|
||||
#ifdef TABLING
|
||||
#define is_tabled(pe) (pe->PredFlags & TabledPredFlag)
|
||||
#endif /* TABLING */
|
||||
@ -1414,7 +1417,7 @@ GetPredPropByFuncAndModHavingLock(FunctorEntry *fe, Term cur_mod) {
|
||||
if (!(p = RepPredProp(fe->PropsOfFE))) {
|
||||
return NIL;
|
||||
}
|
||||
if (p->ModuleOfPred == cur_mod) {
|
||||
if (p->ModuleOfPred == cur_mod || p->ModuleOfPred == 0) {
|
||||
#ifdef THREADS
|
||||
/* Thread Local Predicates */
|
||||
if (p->PredFlags & ThreadLocalPredFlag) {
|
||||
@ -1498,7 +1501,7 @@ INLINE_ONLY EXTERN inline Prop PredPropByAtomAndMod(Atom at, Term cur_mod)
|
||||
p0 = ae->PropsOfAE;
|
||||
while (p0) {
|
||||
PredEntry *pe = RepPredProp(p0);
|
||||
if (pe->KindOfPE == PEProp && (pe->ModuleOfPred == cur_mod)) {
|
||||
if (pe->KindOfPE == PEProp && (pe->ModuleOfPred == cur_mod || pe->ModuleOfPred == 0)) {
|
||||
#ifdef THREADS
|
||||
/* Thread Local Predicates */
|
||||
if (pe->PredFlags & ThreadLocalPredFlag) {
|
||||
|
@ -18,12 +18,15 @@ yap_query = namedtuple( 'yap_query', 'query owner')
|
||||
jupyter_query = namedtuple( 'jupyter_query', 'vars dict')
|
||||
python_query = namedtuple( 'python_query', 'vars dict')
|
||||
yapi_query = namedtuple( 'yapi_query', 'vars dict')
|
||||
show_answer = namedtuple( 'show_answer', 'vars dict')
|
||||
|
||||
def v():
|
||||
return yap.YAPVarTerm()
|
||||
|
||||
def numbervars( q ):
|
||||
Dict = {}
|
||||
if True:
|
||||
engine.goal(yapi_query( q.namedVars(), Dict))
|
||||
engine.goal(show_answer( q.namedVars(), Dict))
|
||||
return Dict
|
||||
rc = q.namedVarsVector()
|
||||
q.r = q.goal().numbervars()
|
||||
@ -42,7 +45,10 @@ def numbervars( q ):
|
||||
|
||||
def answer(q):
|
||||
try:
|
||||
return q.next()
|
||||
v = q.next()
|
||||
if v:
|
||||
print( bindings )
|
||||
return v
|
||||
except Exception as e:
|
||||
print(e.args[1])
|
||||
return False
|
||||
@ -52,7 +58,8 @@ def query_prolog(engine, s):
|
||||
#
|
||||
# construct a query from a one-line string
|
||||
# q is opaque to Python
|
||||
q = engine.query(s)
|
||||
bindings = {}
|
||||
q = engine.query(python_query(s, bindings))
|
||||
# vs is the list of variables
|
||||
# you can print it out, the left-side is the variable name,
|
||||
# the right side wraps a handle to a variable
|
||||
@ -64,10 +71,9 @@ def query_prolog(engine, s):
|
||||
# if not isinstance(eq[0],str):
|
||||
# print( "Error: Variable Name matches a Python Symbol")
|
||||
# return
|
||||
# ask = True
|
||||
ask = True
|
||||
# launch the query
|
||||
while answer(q):
|
||||
print( handler( q ))
|
||||
# deterministic = one solution
|
||||
if q.deterministic():
|
||||
# done
|
||||
@ -98,7 +104,7 @@ def boot_yap(**kwargs):
|
||||
args.setYapLibDir(yap_lib_path)
|
||||
args.setSavedState(os.path.join(yap_lib_path,"startup.yss"))
|
||||
engine = yap.YAPEngine(args)
|
||||
engine.goal( use_module(library('python') ) )
|
||||
engine.goal( use_module(library('yapi') ) )
|
||||
return engine
|
||||
|
||||
def live(**kwargs):
|
||||
|
@ -12,6 +12,7 @@
|
||||
:- use_module( library(maplist) ).
|
||||
:- use_module( library(rbtrees) ).
|
||||
:- use_module( library(terms) ).
|
||||
:- use_module( library(python) ).
|
||||
|
||||
|
||||
%% @pred yap_query(sGoal, + VarList, +OutStream, - Dictionary)
|
||||
@ -20,16 +21,18 @@
|
||||
%% dictionary, Examples
|
||||
%%
|
||||
%%
|
||||
python_query( Engine, String, Dict ) :-
|
||||
python_query( String, D ) :-
|
||||
atomic_to_term( String, Goal, VarNames ),
|
||||
yap_query( Goal, VarNames, user_error, Dict).
|
||||
yap_query( Goal, VarNames, user_error, Dict),
|
||||
D := Dict,
|
||||
yap4py.yapi.bindings := Dict.
|
||||
|
||||
%% @pred yapi_query( + VarList, - Dictionary)
|
||||
%%
|
||||
%% dictionary, Examples
|
||||
%%
|
||||
%%
|
||||
prologun:yapi_query( VarNames, Dict ) :-
|
||||
yapi_query( VarNames, Dict ) :-
|
||||
show_answer(VarNames, Dict).
|
||||
|
||||
|
||||
@ -48,28 +51,42 @@ yap_query( Goal, VarNames, Stream, Dictionary) :-
|
||||
show_answer(VarNames, Stream, Dictionary)
|
||||
).
|
||||
|
||||
yapi_query( VarNames, Dictionary) :-
|
||||
yap_query( VarNames, Dictionary) :-
|
||||
yap_query( VarNames, user_output, Dictionary).
|
||||
|
||||
show_answer(QVs0, Dict) :-
|
||||
show_answer(QVs0, user_error, Dict).
|
||||
|
||||
show_answer(QVs0, Stream, {Dict}) :-
|
||||
show_answer(QVs0, Stream, Dict) :-
|
||||
copy_term(QVs0, QVs),
|
||||
writeln(ivs-IVs),
|
||||
term_variables(Goal, IVs),
|
||||
foldl(enumerate, IVs, 0, _Ns),
|
||||
copy_term(QVs0, QVs1),
|
||||
rb_new(RB),
|
||||
foldl2(bind_qv, QVs, QVs1, [], LP, {}-RB, Dict-_),
|
||||
!,
|
||||
out(QVs, Stream, D).
|
||||
Dictt := {D}.
|
||||
term_variables(QVs, IVs),
|
||||
term_variables(QVs1, IVs1),
|
||||
foldl( enumerate, IVs, IVs1, 1, _ ),
|
||||
out(LP, Stream ).
|
||||
show_answer(_, _, {}) :-
|
||||
format(' yes.~n', [] ).
|
||||
|
||||
bind_qv(V=V0, Vs, Vs) :- var(V0), !, V0='$VAR'(V).
|
||||
bind_qv(V=V, Vs, Vs) :- !.
|
||||
bind_qv(V=S, Vs, [V=S|Vs]).
|
||||
bind_qv(V=V0, V1 = V01, Vs, Vs, Vs1-RB, Vs1-RB) :-
|
||||
var(V0),
|
||||
!,
|
||||
'$VAR'(V) = V0,
|
||||
V1 = V01.
|
||||
% atom_string(V1, V01).
|
||||
bind_qv(V='$VAR'(Vi), V1=S1, Vs, [V='$VAR'(Vi)|Vs], D0-RB, D-RB) :- !,
|
||||
add2dict(D0, V1:S1, D).
|
||||
bind_qv(V=S, V1=S1, Vs, [V=S|Vs], D0-RB0, D-RB0) :-
|
||||
% fix_tree( S, SS, S1, SS1, RB0, RBT),
|
||||
add2dict(D0, V1:S1, D).
|
||||
|
||||
enumerate('$VAR'(A), I, I1) :-
|
||||
|
||||
add2dict({}, B, {B}).
|
||||
add2dict({C}, B, {B,C}).
|
||||
|
||||
enumerate('$VAR'(A), A, I, I1) :-
|
||||
enum(I, Chars),
|
||||
atom_codes(A,[0'_|Chars]),
|
||||
I1 is I + 1.
|
||||
@ -84,65 +101,18 @@ enum(I, [C|Cs]) :-
|
||||
C is "A" +K,
|
||||
enum(J, Cs).
|
||||
|
||||
out(Bs, S, _Dict) :-
|
||||
out(Bs, S) :-
|
||||
output(Bs, S),
|
||||
fail.
|
||||
out(Bs, _S, Dict) :-
|
||||
bvs(Bs, Dict).
|
||||
|
||||
v2py(v(I0) = _V, I0, I) :-
|
||||
!,
|
||||
I is I0+1.
|
||||
v2py(v(I0) = v(I0), I0, I) :-
|
||||
I is I0+1.
|
||||
!.
|
||||
out([_|Bs], S) :-
|
||||
out(Bs, S).
|
||||
|
||||
output([V=B], S) :-
|
||||
!,
|
||||
format(S, '~a = ~q~n', [V, B]).
|
||||
output([V=B|Ns], S) :-
|
||||
output([V=B|_Ns], S) :-
|
||||
format( S, '~a = ~q.~n', [V, B]),
|
||||
output( Ns, S).
|
||||
|
||||
bvs([V=B], S:B) :-
|
||||
atom_atring(V,S),
|
||||
!.
|
||||
bvs([V=B|Ns], (S:B,N) ) :-
|
||||
atom_string(V,S),
|
||||
output( Ns, N).
|
||||
|
||||
bindvars( L, NL ) :-
|
||||
rb_new(T),
|
||||
foldl2( bind, L, NL, T, _ , 0, _),
|
||||
term_variables(NL, Vs),
|
||||
foldl( bind_new, Vs, 0, _).
|
||||
fail.
|
||||
|
||||
|
||||
bind(X=Y, X=X, T0, T, N, N) :-
|
||||
var(Y),
|
||||
!,
|
||||
rb_update(T0, Y, X, T).
|
||||
bind(X = G, X = G, T, T, N0, N0) :-
|
||||
ground(G),
|
||||
!.
|
||||
bind(X = C, X = NC, T, NT, N0, NF) :-
|
||||
C =.. [N|L],
|
||||
foldl2( bind_new, L, NL, T, NT, N0, NF),
|
||||
NC =.. [N|NL].
|
||||
|
||||
bind_new(Y, X, T, T, N, N) :-
|
||||
var(Y),
|
||||
rb_lookup(Y, X, T),
|
||||
!.
|
||||
bind_new(Y, X, T, TN, N, NF) :-
|
||||
var(Y),
|
||||
!,
|
||||
rb_insert(Y, T, X, TN),
|
||||
NF is N+1,
|
||||
atomic_concat('_',N,X).
|
||||
bind_new(Y, Y, T, T, N, N) :-
|
||||
ground(Y),
|
||||
!.
|
||||
bind_new(Y, X, T, NT, N0, NF) :-
|
||||
Y =.. [N|L],
|
||||
foldl2(v, L, NL, T, NT, N0, NF),
|
||||
X =.. [N|NL].
|
||||
|
@ -108,6 +108,7 @@ class YAPEngine;
|
||||
//%typemap(in) YAPTerm { $1 = new YAPTerm(pythonToYAP($input)); PyErr_Clear(); }
|
||||
%typemap(in) YAP_Term { $1 = pythonToYAP($input); PyErr_Clear(); }
|
||||
%typemap(in) Term { $1 = pythonToYAP($input); PyErr_Clear(); }
|
||||
%typemap(in) YAPTerm { YAPTerm(($1 = pythonToYAP($input))); PyErr_Clear(); }
|
||||
|
||||
%typecheck(2) Int { $1 = PyLong_Check($input); }
|
||||
%typecheck(3) double { $1 = PyFloat_Check($input); }
|
||||
|
@ -115,6 +115,7 @@
|
||||
'$discontiguous'(D,M).
|
||||
/** @pred initialization
|
||||
|
||||
|
||||
Execute the goals defined by initialization/1. Only the first answer is
|
||||
considered.
|
||||
|
||||
|
@ -142,7 +142,7 @@ system_error(Type,Goal,Culprit) :-
|
||||
functor(Error, Severity, _),
|
||||
print_message(Severity, Error), !.
|
||||
%'$process_error'(error(Msg, Where), _) :-
|
||||
% print_message(error,error(Msg, [g|Where])), !.
|
||||
% Print_message(error,error(Msg, [g|Where])), !.
|
||||
'$process_error'(Throw, _) :-
|
||||
print_message(error,error(unhandled_exception,Throw)).
|
||||
|
||||
|
@ -108,8 +108,9 @@ In YAP, the infoo field describes:
|
||||
|
||||
:- use_system_module( user, [message_hook/3]).
|
||||
|
||||
%:- start_low_level_trace.
|
||||
:- multifile prolog:message/3.
|
||||
|
||||
%:- stop_low_level_trace.
|
||||
:- multifile user:message_hook/3.
|
||||
|
||||
|
||||
@ -910,7 +911,7 @@ If you need to report errors from your own predicates, we advise you to
|
||||
stick to the existing error terms if you can; but should you need to
|
||||
invent new ones, you can define corresponding error messages by
|
||||
asserting clauses for `prolog:message/2`. You will need to declare
|
||||
the predicate as multifile.
|
||||
the predicate as multifile/1.
|
||||
|
||||
Note: errors in the implementation of print_message/2 are very
|
||||
confusing to YAP (who will process the error?). So we write this small
|
||||
|
@ -60,14 +60,14 @@ 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)
|
||||
Undefined predicate:
|
||||
~~~~~
|
||||
followed by the failure of that call.
|
||||
*/
|
||||
:- multifile user:unknown_predicate_handler/3.
|
||||
|
||||
undefined_query(G0, M0, Cut) :-
|
||||
'$undefp_search'(M0:G0, M:G),
|
||||
recorded('$import','$import'(M,M0,G,G0,_,_),_),
|
||||
'$call'(G, Cut, G, M).
|
||||
|
||||
'$handle_error'(error,Goal,Mod) :-
|
||||
|
Reference in New Issue
Block a user