/************************************************************************* * * * YAP Prolog * * * * Yap Prolog was developed at NCCUP - Universidade do Porto * * * * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 * * * ************************************************************************** * * * File: preds.yap * * Last rev: 8/2/88 * * mods: * * comments: Predicate Manipulation for YAP: declaration support * * * *************************************************************************/ :- system_module( '$_preddecls', [(discontiguous)/1, (dynamic)/1, (multifile)/1], ['$check_multifile_pred'/3, '$discontiguous'/2, '$dynamic'/2]). :- use_system_module( '$_consult', ['$add_multifile'/3]). :- use_system_module( '$_errors', ['$do_error'/2]). % % can only do as goal in YAP mode. % dynamic(X) :- '$access_yap_flags'(8, 0), !, '$current_module'(M), '$dynamic'(X, M). dynamic(X) :- '$do_error'(context_error(dynamic(X),declaration),query). '$dynamic'(X,M) :- var(X), !, '$do_error'(instantiation_error,dynamic(M:X)). '$dynamic'(Mod:Spec,_) :- !, '$dynamic'(Spec,Mod). '$dynamic'([], _) :- !. '$dynamic'([H|L], M) :- !, '$dynamic'(H, M), '$dynamic'(L, M). '$dynamic'((A,B),M) :- !, '$dynamic'(A,M), '$dynamic'(B,M). '$dynamic'(X,M) :- '$dynamic2'(X,M). '$dynamic2'(X, Mod) :- '$log_upd'(Stat), Stat\=0, !, '$logical_updatable'(X, Mod). '$dynamic2'(A//N1, Mod) :- integer(N1), N is N1+2, '$dynamic2'(A/N, Mod). '$dynamic2'(A/N, Mod) :- integer(N), atom(A), !, functor(T,A,N), '$flags'(T,Mod,F,F), % LogUpd,BinaryTest,Safe,C,Dynamic,Compiled,Standard,Asm, ( F/\ 0x19D1FA80 =:= 0, '$undefined'(T,Mod) -> NF is F \/ 0x00002000, '$flags'(T, Mod, F, NF), '$mk_d'(T,Mod); F /\ 0x00002000 =:= 0x00002000 -> '$mk_d'(T,Mod); % dynamic F /\ 0x08000000 =:= 0x08000000 -> '$mk_d'(T,Mod) ; % LU F /\ 0x00000400 =:= 0x00000400, '$undefined'(T,Mod) -> F1 is F /\ \(0x400), N1F is F1 \/ 0x00002000, NF is N1F /\ \(0x00400000), '$flags'(T,Mod,F,NF), '$mk_d'(T,Mod); '$do_error'(permission_error(modify,static_procedure,A/N),dynamic(Mod:A/N)) ). '$dynamic2'(X,Mod) :- '$do_error'(type_error(callable,X),dynamic(Mod:X)). '$logical_updatable'(A//N,Mod) :- integer(N), !, N1 is N+2, '$logical_updatable'(A/N1,Mod). '$logical_updatable'(A/N,Mod) :- integer(N), atom(A), !, functor(T,A,N), '$flags'(T,Mod,F,F), ( F/\ 0x19D1FA80 =:= 0, '$undefined'(T,Mod) -> NF is F \/ 0x08000400, '$flags'(T,Mod,F,NF), '$mk_d'(T,Mod); F /\ 0x08000000 =:= 0x08000000 -> '$mk_d'(T,Mod) ; % LU F /\ 0x00002000 =:= 0x00002000 -> '$mk_d'(T,Mod); % dynamic F /\ 0x00000400 =:= 0x00000400 , '$undefined'(T,Mod) -> N1F is F \/ 0x08000000, NF is N1F /\ \(0x00400000), '$flags'(T,Mod,F,NF), '$mk_d'(T,Mod); '$do_error'(permission_error(modify,static_procedure,A/N),dynamic(Mod:A/N)) ). '$logical_updatable'(X,Mod) :- '$do_error'(type_error(callable,X),dynamic(Mod:X)). multifile(P) :- '$current_module'(OM), '$multifile'(P, M). '$multifile'(V, _) :- var(V), !, '$do_error'(instantiation_error,multifile(V)). '$multifile'((X,Y), M) :- !, '$multifile'(X, M), '$multifile'(Y, M). '$multifile'(Mod:PredSpec, _) :- !, '$multifile'(PredSpec, Mod). '$multifile'(N//A, M) :- !, integer(A), A1 is A+2, '$multifile'(N/A1, M). '$multifile'(N/A, M) :- '$add_multifile'(N,A,M), fail. '$multifile'(N/A, M) :- functor(S,N,A), '$is_multifile'(S, M), !. '$multifile'(N/A, M) :- !, '$new_multifile'(N,A,M). '$multifile'([H|T], M) :- !, '$multifile'(H,M), '$multifile'(T,M). '$multifile'(P, M) :- '$do_error'(type_error(predicate_indicator,P),multifile(M:P)). discontiguous(V) :- var(V), !, '$do_error'(instantiation_error,discontiguous(V)). discontiguous(M:F) :- !, '$discontiguous'(F,M). discontiguous(F) :- '$current_module'(M), '$discontiguous'(F,M). '$discontiguous'(V,M) :- var(V), !, '$do_error'(instantiation_error,M:discontiguous(V)). '$discontiguous'((X,Y),M) :- !, '$discontiguous'(X,M), '$discontiguous'(Y,M). '$discontiguous'(M:A,_) :- !, '$discontiguous'(A,M). '$discontiguous'(N//A1, M) :- !, integer(A1), !, A is A1+2, '$discontiguous'(N/A, M). '$discontiguous'(N/A, M) :- !, ( recordzifnot('$discontiguous_defs','$df'(N,A,M),_) -> true ; true ). '$discontiguous'(P,M) :- '$do_error'(type_error(predicate_indicator,P),M:discontiguous(P)). % % did we declare multifile properly? % '$check_multifile_pred'(Hd, M, _) :- functor(Hd,Na,Ar), source_location(F, _), recorded('$multifile_defs','$defined'(F,Na,Ar,M),_), !. % oops, we did not. '$check_multifile_pred'(Hd, M, Fl) :- % so this is not a multi-file predicate any longer. functor(Hd,Na,Ar), NFl is \(0x20000000) /\ Fl, '$flags'(Hd,M,Fl,NFl), '$warn_mfile'(Na,Ar). '$warn_mfile'(F,A) :- write(user_error,'% Warning: predicate '), write(user_error,F/A), write(user_error,' was a multifile predicate '), write(user_error,' (line '), '$start_line'(LN), write(user_error,LN), write(user_error,')'), nl(user_error).