Prolog library: metutl.pl
pereira at sri-unix.UUCP
pereira at sri-unix.UUCP
Mon Aug 15 15:55:28 AEST 1983
% File : METUTL.PL
% Author : R.A.O'Keefe
% Updated: 20 May 1983
% Purpose: meta-logical operations as described in my note
:- public
compound/1,
copy/2,
ground/1,
occurs_check/2,
occurs_in/2,
simple/1,
subsumes/2,
subsumes_chk/2,
subterm/2,
unify/2,
variables_of/2,
variant/2,
var_member_chk/2.
:- mode
copy(+, ?),
ground(+),
ground(+, +),
occurs_check(+, ?),
occurs_check(+, +, ?),
occurs_in(+, +),
occurs_in(+, +, +),
subterm(+, ?),
subterm(+, +, ?),
subsumes(+, +),
subsumes(+, +, +),
subsumes(+, +, +, +),
subsumes_chk(+, +),
unify(+, +),
unify(+, +, +),
var_member_chk(+, +),
variables_of(+, -),
variables_of(+, +, -),
variables_of(+, +, +, -),
variant(+, +).
compound(Term) :-
nonvar(Term), % not a variable
functor(Term, _, Arity),
Arity > 0. % not atomic
simple(Term) :-
var(Term), !. % is a variable
simple(Term) :- % -or-
functor(Term, Term, 0). % is atomic
ground(Term) :-
nonvar(Term),
functor(Term, _, N),
ground(N, Term).
ground(0, _) :-
!.
ground(N, Term) :-
arg(N, Term, Arg),
ground(Arg),
M is N-1, !,
ground(M, Term).
occurs_in(Var, Term) :-
var(Term),
!,
Var == Term.
occurs_in(Var, Term) :-
functor(Term, _, N),
occurs_in(N, Var, Term).
occurs_in(N, Var, Term) :-
arg(N, Term, Arg),
occurs_in(Var, Arg),
!.
occurs_in(N, Var, Term) :-
N > 1,
M is N-1,
occurs_in(M, Var, Term).
subterm(Term, Term).
subterm(SubTerm, Term) :-
nonvar(Term),
functor(Term, _, N),
subterm(N, SubTerm, Term).
subterm(N, SubTerm, Term) :-
arg(N, Term, Arg),
subterm(SubTerm, Arg).
subterm(N, SubTerm, Term) :-
N > 1,
M is N-1,
subterm(M, SubTerm, Term).
copy(Old, New) :-
asserta(copy(Old)),
retract(copy(Mid)), !,
New = Mid.
occurs_check(Term, Var) :-
var(Term), !,
Term \== Var.
occurs_check(Term, Var) :-
functor(Term, _, Arity),
occurs_check(Arity, Term, Var).
occurs_check(0, _, _) :- !.
occurs_check(N, Term, Var) :-
arg(N, Term, Arg),
occurs_check(Arg, Var),
M is N-1, !,
occurs_check(M, Term, Var).
unify(X, Y) :-
var(X), var(Y),
!,
X = Y. % want unify(X,X)
unify(X, Y) :-
var(X),
!,
occurs_check(Y, X), % X is not in Y
X = Y.
unify(X, Y) :-
var(Y),
!,
occurs_check(X, Y), % Y is not in X
X = Y.
unify(X, Y) :-
atomic(X),
!,
X = Y.
unify(X, Y) :-
functor(X, F, N),
functor(Y, F, N),
unify(N, X, Y).
unify(0, X, Y) :- !.
unify(N, X, Y) :-
arg(N, X, Xn),
arg(N, Y, Yn),
unify(Xn, Yn),
M is N-1, !,
unify(M, X, Y).
subsumes_chk(General, Specific) :-
\+ ( numbervars(Specific, 0, _),
\+ General = Specific
).
var_member_chk(Var, [Head|_]) :-
Head == Var,
!.
var_member_chk(Var, [_|Tail]) :-
var_member_chk(Var, Tail).
variables_of(Term, Vars) :-
variables_of(Term, [], Vars).
variables_of(Term, Sofar, Sofar) :-
var(Term),
var_member_chk(Term, Sofar),
!.
variables_of(Term, Sofar, [Term|Sofar]) :-
var(Term),
!.
variables_of(Term, Sofar, Vars) :-
functor(Term, _, N),
variables_of(N, Term, Sofar, Vars).
variables_of(0, _, Vars, Vars) :- !.
variables_of(N, Term, Sofar, Vars) :-
arg(N, Term, Arg),
variables_of(Arg, Sofar, Mid),
M is N-1, !,
variables_of(M, Term, Mid, Vars).
subsumes(General, Specific) :-
variables_of(Specific, Vars),
subsumes(General, Specific, Vars).
subsumes(General, Specific, Vars) :-
var(General),
var_member_chk(General, Vars),
!,
General == Specific.
subsumes(General, Specific, Vars) :-
var(General),
!,
General = Specific. % binds
subsumes(General, Specific, Vars) :-
nonvar(Specific), % mustn't bind it
functor(General, FunctionSymbol, Arity),
functor(Specific, FunctionSymbol, Arity),
subsumes(Arity, General, Specific, Vars).
subsumes(0, _, _, _) :- !.
subsumes(N, General, Specific, Vars) :-
arg(N, General, GenArg),
arg(N, Specific, SpeArg),
subsumes(GenArg, SpeArg, Vars),
M is N-1, !,
subsumes(M, General, Specific, Vars).
variant(A, B) :-
subsumes_chk(A, B),
subsumes_chk(B, A).
More information about the Comp.sources.unix
mailing list