160 lines
5.0 KiB
Prolog
160 lines
5.0 KiB
Prolog
/*************************************************************************
|
|
* *
|
|
* 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).
|
|
|