1193323Sed
2193323Sed%   File   : METUTL.PL
3193323Sed%   Author : R.A.O'Keefe
4193323Sed%   Updated: 15 September 1984
5193323Sed%   Purpose: meta-logical operations as described in my note
6193323Sed
7193323Sed:- module(metutl).			% SEPIA header
8193323Sed:- local unify/3.
9193323Sed:- export
10193323Sed%	compound/1,			% is a Sepia builtin
11193323Sed	copy/2,				% use copy_term/2 instead
12193323Sed	ground/1,			% better use \+ nonground
13193323Sed	occurs_check/2,			% better use \+ occurs
14193323Sed	occurs_in/2,			% use occurs/2 instead
15193323Sed	simple/1,
16193323Sed	subsumes/2,
17193323Sed	subsumes_chk/2,
18193323Sed	subterm/2,
19193323Sed	unify/2,
20193323Sed	variables_of/2,
21193323Sed	variant/2,			% less restricted than the builtin
22193323Sed	var_member_chk/2.
23249423Sdim
24249423Sdim:- lib(numbervars).
25249423Sdim
26198090Srdivacky/* the declarations are partially wrong for SEPIA
27193323Sed:- mode
28198892Srdivacky	copy(+, ?),
29193323Sed	ground(+),
30249423Sdim	    ground(+, +),
31193323Sed	occurs_check(+, ?),
32198892Srdivacky	    occurs_check(+, +, ?),
33193323Sed	occurs_in(+, +),
34193323Sed	    occurs_in(+, +, +),
35193323Sed	subterm(+, ?),
36193323Sed	    subterm(+, +, ?),
37249423Sdim	subsumes(+, +),
38263508Sdim	    subsumes(+, +, +),
39239462Sdim		subsumes(+, +, +, +),
40193323Sed	subsumes_chk(+, +),
41239462Sdim	unify(+, +),
42193323Sed	    unify(+, +, +),
43193323Sed	var_member_chk(+, +),
44193323Sed	variables_of(+, -),
45193323Sed	    variables_of(+, +, -),
46193323Sed		variables_of(+, +, +, -),
47193323Sed	variant(+, +).
48212904Sdim*/
49193323Sed
50239462Sdim
51239462Sdim% compound(Term) :-
52239462Sdim% 	nonvar(Term),		%  not a variable
53239462Sdim% 	functor(Term, _, Arity),
54239462Sdim% 	Arity > 0.		%  not atomic
55239462Sdim
56239462Sdim
57239462Sdim% simple(?T)
58239462Sdim% True if T is an uninstantiated variable or an atom.
59193323Sed
60193323Sedsimple(Term) :-
61193323Sed	var(Term), !.			%  is a variable
62206083Srdivackysimple(Term) :-				%  -or-
63193323Sed	atomic(Term).			%  is a number or an atom.
64239462Sdim
65239462Sdim
66193323Sed% ground(+Term)
67234353Sdim% True if Term is ground, that is, it contains no
68234353Sdim% uninstantiated variables.
69234353Sdim
70234353Sdimground(Term) :-
71234353Sdim	nonvar(Term),
72234353Sdim	functor(Term, _, N),
73234353Sdim	ground(N, Term).
74234353Sdim
75234353Sdimground(0, _) :-
76234353Sdim	!.
77234353Sdim
78234353Sdimground(N, Term) :-
79234353Sdim	arg(N, Term, Arg),
80234353Sdim	ground(Arg),
81234353Sdim	M is N-1, !,
82234353Sdim	ground(M, Term).
83234353Sdim
84234353Sdim
85234353Sdim% occurs_in(-Var,+Term)
86234353Sdim% True if the variable Var occurs somewhere in Term
87234353Sdim% For instance
88234353Sdim%	occurs_in(X,foo(X)) is true.
89234353Sdim
90234353Sdimoccurs_in(Var, Term) :- occurs(Var, Term).	% SEPIA
91234353Sdim
92234353Sdim% occurs_in(Var, Term) :-
93263508Sdim% 	var(Term),
94263508Sdim% 	!,
95263508Sdim% 	Var == Term.
96239462Sdim%
97193323Sed% occurs_in(Var, Term) :-
98193323Sed% 	functor(Term, _, N),
99239462Sdim% 	occurs_in(N, Var, Term).
100239462Sdim%
101193323Sed% occurs_in(N, Var, Term) :-
102204642Srdivacky% 	arg(N, Term, Arg),
103263508Sdim% 	occurs_in(Var, Arg),
104204642Srdivacky% 	!.
105239462Sdim%
106263508Sdim% occurs_in(N, Var, Term) :-
107263508Sdim% 	N > 1,
108263508Sdim% 	M is N-1,
109263508Sdim% 	occurs_in(M, Var, Term).
110193323Sed
111193323Sed
112239462Sdim% subterm(+S,+T)
113239462Sdim% true if S is a subterm of T (including if S = T)
114193323Sed
115193323Sedsubterm(Term, Term).
116239462Sdim
117239462Sdimsubterm(SubTerm, Term) :-
118193323Sed	nonvar(Term),
119193323Sed	functor(Term, _, N),
120239462Sdim	subterm(N, SubTerm, Term).
121263508Sdim
122263508Sdimsubterm(N, SubTerm, Term) :-
123263508Sdim	arg(N, Term, Arg),
124263508Sdim	subterm(SubTerm, Arg).
125263508Sdim
126193323Sedsubterm(N, SubTerm, Term) :-
127207618Srdivacky	N > 1,
128263508Sdim	M is N-1,
129263508Sdim	subterm(M, SubTerm, Term).
130263508Sdim
131263508Sdim
132263508Sdim% copy(+Old,-New)
133263508Sdim% Makes a fresh copy of the term Old. A bit hacky...
134239462Sdim
135239462Sdimcopy(Old, New) :- copy_term(Old, New).	% SEPIA
136239462Sdim
137239462Sdim% copy(Old, New) :-			% Altered to use data base
138207618Srdivacky% 	record(copy,Old,Key),		% KJ  21-5-87
139212904Sdim% 	recorded(copy,Mid,Key),
140263508Sdim% 	erase(Key),
141263508Sdim% 	!,
142263508Sdim% 	New = Mid.
143263508Sdim
144193323Sed
145218893Sdim% unify(?X, ?Y)
146218893Sdim% Try to unify X and Y, wih occurs check.
147218893Sdim% Further down in this file is the Occurs Check.
148218893Sdim
149221345Sdimunify(X, Y) :-
150221345Sdim	var(X),
151221345Sdim	var(Y),
152221345Sdim	!,
153221345Sdim	X = Y.				%  want unify(X,X)
154218893Sdim
155243830Sdimunify(X, Y) :-
156243830Sdim	var(X),
157243830Sdim	!,
158243830Sdim	occurs_check(Y, X),		%  X is not in Y
159243830Sdim	X = Y.
160243830Sdim
161243830Sdimunify(X, Y) :-
162243830Sdim	var(Y),
163263508Sdim	!,
164243830Sdim	occurs_check(X, Y),		%  Y is not in X
165243830Sdim	X = Y.
166243830Sdim
167243830Sdimunify(X, Y) :-
168243830Sdim	atomic(X),
169243830Sdim	!,
170243830Sdim	X = Y.
171243830Sdim
172243830Sdimunify(X, Y) :-
173243830Sdim	functor(X, F, N),
174243830Sdim	functor(Y, F, N),
175239462Sdim	unify(N, X, Y).
176239462Sdim
177193323Sedunify(0, _, _) :- !.
178193323Sed
179239462Sdimunify(N, X, Y) :-
180239462Sdim	arg(N, X, Xn),
181218893Sdim	arg(N, Y, Yn),
182218893Sdim	unify(Xn, Yn),
183193323Sed	M is N-1,
184193323Sed	!,
185198892Srdivacky	unify(M, X, Y).
186239462Sdim
187193323Sedoccurs_check(Term, Var) :- \+ occurs(Var, Term).	% SEPIA
188193323Sed
189198892Srdivacky% occurs_check(Term, Var) :-
190198892Srdivacky% 	var(Term),
191239462Sdim% 	!,
192198892Srdivacky% 	Term \== Var.
193212904Sdim%
194198892Srdivacky% occurs_check(Term, Var) :-
195198892Srdivacky% 	functor(Term, _, Arity),
196239462Sdim% 	occurs_check(Arity, Term, Var).
197198892Srdivacky%
198198892Srdivacky% occurs_check(0, _, _) :- !.
199198892Srdivacky%
200198892Srdivacky% occurs_check(N, Term, Var) :-
201239462Sdim% 	arg(N, Term, Arg),
202212904Sdim% 	occurs_check(Arg, Var),
203198892Srdivacky% 	M is N-1,
204198892Srdivacky% 	!,
205198892Srdivacky% 	occurs_check(M, Term, Var).
206239462Sdim
207212904Sdimvar_member_chk(Var, [Head|_]) :-
208198892Srdivacky	Head == Var,
209263508Sdim	!.
210212904Sdimvar_member_chk(Var, [_|Tail]) :-
211263508Sdim	var_member_chk(Var, Tail).
212212904Sdim
213212904Sdim
214263508Sdimvariables_of(Term, Vars) :-
215212904Sdim	variables_of(Term, [], Vars).
216263508Sdim
217212904Sdimvariables_of(Term, Sofar, Sofar) :-
218212904Sdim	var(Term),
219198892Srdivacky	var_member_chk(Term, Sofar),
220239462Sdim	!.
221198892Srdivackyvariables_of(Term, Sofar, [Term|Sofar]) :-
222198892Srdivacky	var(Term),
223249423Sdim	!.
224249423Sdimvariables_of(Term, Sofar, Vars) :-
225249423Sdim	functor(Term, _, N),
226249423Sdim	variables_of(N, Term, Sofar, Vars).
227249423Sdim
228249423Sdimvariables_of(0, _, Vars, Vars) :- !.
229249423Sdimvariables_of(N, Term, Sofar, Vars) :-
230199481Srdivacky	arg(N, Term, Arg),
231239462Sdim	variables_of(Arg, Sofar, Mid),
232198892Srdivacky	M is N-1, !,
233198892Srdivacky	variables_of(M, Term, Mid, Vars).
234263508Sdim
235263508Sdim
236263508Sdim% subsumes(+General, +Specific)
237263508Sdim% True if Specific can be found by instantiating variables in General
238263508Sdim% for instance, subsumes(foo(X), foo(bar)) is true.
239263508Sdim
240193323Sedsubsumes(General, Specific) :-
241239462Sdim	variables_of(Specific, Vars),
242193323Sed	subsumes(General, Specific, Vars).
243193323Sed
244193323Sedsubsumes(General, Specific, Vars) :-
245239462Sdim	var(General),
246193323Sed	var_member_chk(General, Vars),
247193323Sed	!,
248198892Srdivacky	General == Specific.
249198892Srdivacky
250239462Sdimsubsumes(General, Specific, _) :-
251198892Srdivacky	var(General),
252198892Srdivacky	!,
253206083Srdivacky	General = Specific.			%  binds
254193323Sed
255193323Sedsubsumes(General, Specific, Vars) :-
256193323Sed	nonvar(Specific),			%  mustn't bind it
257193323Sed	functor(General,  FunctionSymbol, Arity),
258193323Sed	functor(Specific, FunctionSymbol, Arity),
259193323Sed	subsumes(Arity, General, Specific, Vars).
260193323Sed
261193323Sedsubsumes(0, _, _, _) :- !.
262198090Srdivacky
263193323Sedsubsumes(N, General, Specific, Vars) :-
264234353Sdim	arg(N, General,  GenArg),
265234353Sdim	arg(N, Specific, SpeArg),
266234353Sdim	subsumes(GenArg, SpeArg, Vars),
267234353Sdim	M is N-1, !,
268193323Sed	subsumes(M, General, Specific, Vars).
269239462Sdim
270239462Sdim
271239462Sdimvariant(A, B) :-
272239462Sdim	subsumes_chk(A, B),
273234353Sdim	subsumes_chk(B, A).
274234353Sdim
275243830Sdimsubsumes_chk(General, Specific) :-
276193323Sed	\+  (	numbervars(Specific, 0, _),
277234353Sdim		\+ General = Specific
278234353Sdim	    ).
279234353Sdim
280234353Sdim